scclib
Stable Cloud Computing C++ Library
Public Types | Public Member Functions | List of all members

Poller which allows polling of generic file descriptors for various events. More...

#include <poller.h>

Public Types

enum  PollFlag {
  input = 0x1 , output = 0x2 , read_hup = 0x4 , priority = 0x8 ,
  hup = 0x10 , error = 0x20
}
 Polling flags. More...
 

Public Member Functions

 Poller (const Poller &)=delete
 
void operator= (const Poller &)=delete
 
 Poller (Poller &&)=delete
 
const Polleroperator= (Poller &&)=delete
 
void set (int, int)
 Add a file desriptor to poller. More...
 
void remove (int)
 Remove a file descriptor from poller. More...
 
void wait ()
 Wait forever for an event.
 
void wait (std::chrono::milliseconds t)
 Wait for a number of milliseconds for an event.
 
int event (int)
 Return flags which were polled for this file descriptor. More...
 

Detailed Description

Poller which allows polling of generic file descriptors for various events.

Examples of valid descriptors are pipes and stream (TCP) sockets.

After a wait(), the poller can be tested to see which events have been polled.

Example from scclib/net/unittest/inet.cc using a Poller to wait for Event

TEST(inet_example, client_server_stream_test)
{
Logger log;
log.add_cout();
log.id("tcp client");
// this test sets up a client and server & streams some data between them
addr.host("::1"); // localhost
addr.port(9999);
// listening event
scc::util::Event listening;
std::packaged_task<int(void)> serv_task([&addr, &listening]()
{
Logger log;
log.add_cout();
log.id("tcp server");
try
{
sock.reuse_addr(true);
sock.bind(addr);
log << "server listening" << endl;
sock.listen();
// can play around with timeouts and timing this way...
//log << "sleep for a second" << endl;
//std::this_thread::sleep_for(std::chrono::seconds(1));
log << "signalling client" << endl;
listening.write(1);
auto conn = sock.accept(from);
log << "connection from " << from << endl;
scc::util::IoStream stream(conn, conn);
int count = 0;
for (string got; std::getline(stream, got);) // loop until eof (socket closed)
{
log << "got " << got << endl;
count += got.size();
stream << got << endl;
}
return count;
}
catch (exception& ex)
{
log << ex.what() << endl;
listening.write(1);
return -1;
}
});
auto fut = serv_task.get_future();
std::thread serv(std::move(serv_task)); // start server thread
Poller pin;
pin.set(listening, Poller::input);
while (1)
{
pin.wait(std::chrono::milliseconds(700));
if (pin.event(listening))
{
break;
}
log << "waiting for listener" << endl;
}
listening.read();
// use a non-blocking approach to add a timeout to the connect
sock.non_blocking(true);
error_code ec;
sock.connect(addr, ec);
if (ec.value() != 0 && ec.value() != EINPROGRESS)
{
log << "Non blocking connect failed: " << ec.message() << endl;
ASSERT_EQ(ec.value(), 0);
}
log << "waiting for 200 ms seconds to connect" << endl;
Poller pout;
pout.set(sock, Poller::output);
pout.wait(std::chrono::milliseconds(200));
if (!pout.event(sock))
{
log << "connect attempt timed out" << endl;
ASSERT_EQ(pout.event(sock), 0);
}
sock.non_blocking(false);
sock.connect(addr); // connect will either throw immediately or connect
log << "connected, sending stuff" << endl;
string line1("first line");
string line2("second line");
scc::util::IoStream stream(sock, sock);
string got;
ASSERT_TRUE(stream << line1 << endl);
ASSERT_TRUE(getline(stream, got));
ASSERT_EQ(got, line1);
ASSERT_TRUE(stream << line2 << endl);
ASSERT_TRUE(getline(stream, got));
ASSERT_EQ(got, line2);
sock.close();
serv.join();
int res = fut.get();
log << "got result=" << res << endl;
ASSERT_EQ(res, line1.size()+line2.size());
}
Ipv6 internet address.
Definition: inet.h:120
unsigned port() const
Get the port.
Definition: inet.cc:159
virtual std::string host() const
Get host.
Definition: inet.cc:188
Internet transmission control protocol (tcp) socket.
Definition: inet.h:251
Signaling kernel event counter.
Definition: event.h:79
uint64_t read()
Read from (decrement) the event counter.
Definition: event.cc:82
void write(uint64_t)
Write to (increment) the event counter.
Definition: event.cc:94
Input/output stream wrapper for reader/writer.
Definition: iostream.h:157
@ output
File descriptor is available for write operations.
Definition: poller.h:78
@ input
File descriptor is available for read operations.
Definition: poller.h:77
TEST(inet_example, client_server_stream_test)
[Inet client server]
Definition: inet.cc:521
Examples
examples/net/netmain.cc, net/unittest/inet.cc, net/unittest/inet_stream.cc, net/unittest/unix.cc, and util/unittest/poller.cc.

Definition at line 65 of file poller.h.

Member Enumeration Documentation

◆ PollFlag

Polling flags.

Enumerator
input 

File descriptor is available for read operations.

output 

File descriptor is available for write operations.

read_hup 

For stream sockets, peer connection (or local connection) has been shut down.

priority 

There is some exceptional condition on the file descriptor. E.g. There is out-of-band data on a TCP socket.

hup 

Hang up. The local or peer connection has been closed.

error 

Error condition.

Definition at line 75 of file poller.h.

Member Function Documentation

◆ event()

int Poller::event ( int  fd)

Return flags which were polled for this file descriptor.

Parameters
fdFile descriptor
Returns
0 No event was polled for this descriptor
event Logical OR of poll flags, see: PollFlag

Definition at line 171 of file poller.cc.

◆ remove()

void Poller::remove ( int  fd)

Remove a file descriptor from poller.

Parameters
fdFile descriptor

Definition at line 101 of file poller.cc.

◆ set()

void Poller::set ( int  fd,
int  flags 
)

Add a file desriptor to poller.

Only input, output, read_hup or priority must be specified, hup and error are automatically polled.

Parameters
fdFile descriptor
flagsLogical OR of polling flags, see: PollFlag

Definition at line 54 of file poller.cc.


The documentation for this class was generated from the following files: