Passenger::EventedClient Class Reference

A utility class for making I/O handling in non-blocking libev evented servers much easier. More...

#include <EventedClient.h>

Inherited by Passenger::EventedMessageClient.

List of all members.

Public Types

enum  { DISCONNECT_FULL, DISCONNECT_WRITE }
 

Controls what to do when a write error is encountered.

More...

Public Member Functions

 EventedClient (struct ev_loop *loop, const FileDescriptor &_fd)
 Creates a new EventedClient with the given libev loop and file descriptor.
void ref ()
 Increase reference count.
void unref ()
 Decrease reference count.
bool ioAllowed () const
 Returns whether it is allowed to perform some kind of I/O with this client, either reading or writing.
bool writeAllowed () const
 Returns whether it is allowed to write data to the client.
bool readWatcherActive () const
 Used by unit tests.
size_t pendingWrites () const
 Returns the number of bytes that are scheduled to be sent to the client at a later time.
void notifyReads (bool enable)
 Sets whether you're interested in read events.
void setOutboxLimit (unsigned int size)
 Sets a limit on the client outbox.
void write (const StaticString data[], unsigned int count)
 Sends data to this client.
void closeWrite ()
 Close only the writer side of the client connection.
void disconnect (bool force=false)
 Disconnects the client.
FileDescriptor detach ()
 Detaches the client file descriptor so that this EventedClient no longer has any control over it.

Public Attributes

FileDescriptor fd
 The client's file descriptor.
enum
Passenger::EventedClient:: { ... }  
writeErrorAction
 Controls what to do when a write error is encountered.
Callback onReadable
 Called when the file descriptor becomes readable and read notifications are enabled (see notifyRead()).
Callback onDisconnect
 Called when the client is disconnected.
Callback onDetach
 Called when detach() is called for the first time.
Callback onPendingDataFlushed
 Called after all pending outgoing data have been written out.
SystemErrorCallback onSystemError
 System call errors are reported with this callback.
void * userData
 EventedClient doesn't do anything with this.

Detailed Description

A utility class for making I/O handling in non-blocking libev evented servers much easier.

Basic usage

Construct an EventedClient with a libev loop and a file descriptor:

 EventedClient *client = new EventedClient(loop, fd);

You are probably interested in read readiness notifications on fd. However these notifications are disabled by default. You need to set the onReadable callback (which is called every time the fd is readable) and enable read notifications.

 void onReadable(EventedClient *client) {
     // do whatever you want
 }
 
 ...
 client->onReadable = onReadable;
 client->notifyReads(true);

Error handling

EventedClient never raises exceptions, except when your callbacks do. It reports errors with the onSystemError callback. That said, EventedClient is exception-aware and will ensure that its internal state stays consistent even when your callbacks throw exceptions.


Member Enumeration Documentation

anonymous enum

Controls what to do when a write error is encountered.

Enumerator:
DISCONNECT_FULL 

Forcefully disconnect the client.

DISCONNECT_WRITE 

Close the writer side of the connection, but continue allowing reading.


Constructor & Destructor Documentation

Passenger::EventedClient::EventedClient ( struct ev_loop *  loop,
const FileDescriptor _fd 
) [inline]

Creates a new EventedClient with the given libev loop and file descriptor.

The initial reference count is 1.


Member Function Documentation

void Passenger::EventedClient::closeWrite (  )  [inline]

Close only the writer side of the client connection.

After calling this method, subsequent write() calls won't do anything anymore. Any pending outgoing data will be sent out whenever the opportunity arises.

This function does nothing if the client is being disconnected, already disconnected or if only the writer side is closed.

FileDescriptor Passenger::EventedClient::detach (  )  [inline]

Detaches the client file descriptor so that this EventedClient no longer has any control over it.

Any EventedClient I/O watchers on the client file descriptor will be stopped and further I/O on the file descriptor via EventedClient will become impossible. Any pending outgoing data will be discarded. The original client file descriptor is returned and onDetach is called. Subsequent calls to this function will return -1 and will no longer call onDetach.

Postcondition:
!ioAllowed()
fd == -1
void Passenger::EventedClient::disconnect ( bool  force = false  )  [inline]

Disconnects the client.

This actually closes the underlying file descriptor, even if the FileDescriptor object still has references.

If force is true then the client will be disconnected immediately, and any pending outgoing data will be discarded. Otherwise the client will be disconnected after all pending outgoing data have been sent; in the mean time no new data can be received from or sent to the client.

After the client has actually been disconnected (which may be either immediately or after a short period of time), a disconnect event will be emitted.

If the client connection has already been closed then this method does nothing. If the client connection is being closed (because there's pending outgoing data) then the behavior depends on the force argument: if true then the connection is closed immediately and the pending data is discarded, otherwise this method does nothing.

The onDisconnect callback will be called after the file descriptor is closed, which is either immediately or after all pending data has been sent out.

bool Passenger::EventedClient::ioAllowed (  )  const [inline]

Returns whether it is allowed to perform some kind of I/O with this client, either reading or writing.

Usually true, and false when the client is either being disconnected or has been disconnected. A return value of false indicates that fd might be -1, but even when it isn't -1 you shouldn't access fd anymore. When the connection is half-closed (e.g. after closeWrite() has been called) the return value is still be true. Only when I/O of any kind is disallowed will this function return false.

void Passenger::EventedClient::notifyReads ( bool  enable  )  [inline]

Sets whether you're interested in read events.

This will start or stop the input readiness watcher appropriately according to the current state.

If the client connection is already being closed or has already been closed then this method does nothing.

size_t Passenger::EventedClient::pendingWrites (  )  const [inline]

Returns the number of bytes that are scheduled to be sent to the client at a later time.

See also:
write()
bool Passenger::EventedClient::readWatcherActive (  )  const [inline]

Used by unit tests.

void Passenger::EventedClient::setOutboxLimit ( unsigned int  size  )  [inline]

Sets a limit on the client outbox.

The outbox is where data is stored that could not be immediately sent to the client, e.g. because of network congestion. Whenver the outbox's size grows past this limit, EventedClient will enter a state in which it will stop listening for read events and instead concentrate on sending out all pending data.

Setting this to 0 means that the outbox has an unlimited size. Please note however that this also means that the outbox's memory could grow unbounded if the client is too slow at receiving data.

The default value is some non-zero value.

If the client connection is already being closed or has already been closed then this method does nothing.

void Passenger::EventedClient::unref (  )  [inline]

Decrease reference count.

Upon reaching 0, this EventedClient object will be destroyed.

void Passenger::EventedClient::write ( const StaticString  data[],
unsigned int  count 
) [inline]

Sends data to this client.

This method will try to send the data immediately (in which no intermediate copies of the data will be made), but if the client is not yet ready to receive data (e.g. because of network congestion) then the data will be buffered and scheduled for sending later.

If an I/O error was encountered then the action taken depends on the value of writeActionError. By default it is DISCONNECT_FULL, meaning the client connection will be closed by calling disconnect(true). This means this method could potentially call the onDisconnect callback.

If the client connection is already being closed, has already been closed or if the writer side is closed, then this method does nothing.

The onPendingDataFlushed callback will be called after this data and whatever existing pending data have been written out. That may either be immediately or after a short period of of time.

bool Passenger::EventedClient::writeAllowed (  )  const [inline]

Returns whether it is allowed to write data to the client.

Usually true, and false when the client is either being disconnected or has been disconnected or when the writer side of the client connection has been closed. write() will do nothing if this function returns false.


Member Data Documentation

The client's file descriptor.

Could be -1: see ioAllowed().

Called when the client is disconnected.

This happens either immediately when disconnect() is called, or a short amount of time later. See the documentation for that function for details.

Please note that destroying an EventedClient object does *not* cause this callback to be called.

Called after all pending outgoing data have been written out.

If write() can be completed immediately without scheduling data for later, then write() will call this callback immediately after writing.

Called when the file descriptor becomes readable and read notifications are enabled (see notifyRead()).

When there's too much pending outgoing data, readability notifications are temporarily disabled; see write() for details.

EventedClient doesn't do anything with this.

Set it to whatever you want.

Controls what to do when a write error is encountered.


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

Generated by  doxygen 1.6.2