* EINPROGRESS. An event MAY be sent at any time that writes will not
* block.
*
- * Before calling HandleEvent, a socket engine MAY change the state of
+ * Before calling OnEventHandler*(), a socket engine MAY change the state of
* the FD back to FD_WANT_EDGE_WRITE if it is simpler (for example, if a
* one-shot notification was registered). If further writes are needed,
* it is the responsibility of the event handler to change the state to
*/
FD_WANT_EDGE_WRITE = 0x80,
/** Request a one-shot poll-style write notification. The socket will
- * return to the FD_WANT_NO_WRITE state before HandleEvent is called.
+ * return to the FD_WANT_NO_WRITE state before OnEventHandler*() is called.
*/
FD_WANT_SINGLE_WRITE = 0x100,
FD_WANT_WRITE_MASK = 0x1F0,
/** Add a trial read. During the next DispatchEvents invocation, this
- * will call HandleEvent with EVENT_READ unless reads are known to be
+ * will call OnEventHandlerRead() unless reads are known to be
* blocking.
*/
FD_ADD_TRIAL_READ = 0x1000,
/** Assert that reads are known to block. This cancels FD_ADD_TRIAL_READ.
- * Reset by SE before running EVENT_READ
+ * Reset by SE before running OnEventHandlerRead().
*/
FD_READ_WILL_BLOCK = 0x2000,
/** Add a trial write. During the next DispatchEvents invocation, this
- * will call HandleEvent with EVENT_WRITE unless writes are known to be
+ * will call OnEventHandlerWrite() unless writes are known to be
* blocking.
*
* This could be used to group several writes together into a single
*/
FD_ADD_TRIAL_WRITE = 0x4000,
/** Assert that writes are known to block. This cancels FD_ADD_TRIAL_WRITE.
- * Reset by SE before running EVENT_WRITE
+ * Reset by SE before running OnEventHandlerWrite().
*/
FD_WRITE_WILL_BLOCK = 0x8000,
/** This class is a basic I/O handler class.
* Any object which wishes to receive basic I/O events
* from the socketengine must derive from this class and
- * implement the HandleEvent() method. The derived class
+ * implement the OnEventHandler*() methods. The derived class
* must then be added to SocketEngine using the method
* SocketEngine::AddFd(), after which point the derived
- * class will receive events to its HandleEvent() method.
- * The derived class should also implement one of Readable()
- * and Writeable(). In the current implementation, only
- * Readable() is used. If this returns true, the socketengine
- * inserts a readable socket. If it is false, the socketengine
- * inserts a writeable socket. The derived class should never
- * change the value this function returns without first
- * deleting the socket from the socket engine. The only
+ * class will receive events to its OnEventHandler*() methods.
+ * The event mask passed to SocketEngine::AddFd() determines
+ * what events the EventHandler gets notified about and with
+ * what semantics. SocketEngine::ChangeEventMask() can be
+ * called to update the event mask later. The only
* requirement beyond this for an event handler is that it
* must have a file descriptor. What this file descriptor
* is actually attached to is completely up to you.
* its private members and internal behaviour
* should be treated as blackboxed, and vary
* from system to system and upon the config
- * settings chosen by the server admin. The current
- * version supports select, epoll and kqueue.
- * The configure script will enable a socket engine
- * based upon what OS is detected, and will derive
- * a class from SocketEngine based upon what it finds.
- * The derived classes file will also implement a
- * classfactory, SocketEngineFactory, which will
- * create a derived instance of SocketEngine using
- * polymorphism so that the core and modules do not
- * have to be aware of which SocketEngine derived
- * class they are using.
+ * settings chosen by the server admin.
*/
class CoreExport SocketEngine
{
*/
Statistics() : lastempty(0), TotalEvents(0), ReadEvents(0), WriteEvents(0), ErrorEvents(0) { }
- /** Increase the counters for bytes sent/received in this second.
- * @param len_in Bytes received, 0 if updating number of bytes written.
- * @param len_out Bytes sent, 0 if updating number of bytes read.
+ /** Update counters for network data received.
+ * This should be called after every read-type syscall.
+ * @param len_in Number of bytes received, or -1 for error, as typically
+ * returned by a read-style syscall.
*/
- void Update(size_t len_in, size_t len_out);
+ void UpdateReadCounters(int len_in);
+
+ /** Update counters for network data sent.
+ * This should be called after every write-type syscall.
+ * @param len_out Number of bytes sent, or -1 for error, as typically
+ * returned by a read-style syscall.
+ */
+ void UpdateWriteCounters(int len_out);
/** Get data transfer statistics.
- * @param kbitspersec_in Filled with incoming traffic in this second in kbit/s.
- * @param kbitspersec_out Filled with outgoing traffic in this second in kbit/s.
- * @param kbitspersec_total Filled with total traffic in this second in kbit/s.
+ * @param kbitpersec_in Filled with incoming traffic in this second in kbit/s.
+ * @param kbitpersec_out Filled with outgoing traffic in this second in kbit/s.
+ * @param kbitpersec_total Filled with total traffic in this second in kbit/s.
*/
void CoreExport GetBandwidth(float& kbitpersec_in, float& kbitpersec_out, float& kbitpersec_total) const;
**/
static std::vector<EventHandler*> ref;
- protected:
- /** Current number of descriptors in the engine
- */
+ /** Current number of descriptors in the engine. */
static size_t CurrentSetSize;
+
+ /** The maximum number of descriptors in the engine. */
+ static size_t MaxSetSize;
+
/** List of handlers that want a trial read/write
*/
static std::set<int> trials;
- static int MAX_DESCRIPTORS;
-
/** Socket engine statistics: count of various events, bandwidth usage
*/
static Statistics stats;
+ /** Look up the fd limit using rlimit. */
+ static void LookupMaxFds();
+
+ /** Terminates the program when the socket engine fails to initialize. */
+ static void InitError();
+
static void OnSetEvent(EventHandler* eh, int old_mask, int new_mask);
/** Add an event handler to the base socket engine. AddFd(EventHandler*, int) should call this.
/** Add an EventHandler object to the engine. Use AddFd to add a file
* descriptor to the engine and have the socket engine monitor it. You
* must provide an object derived from EventHandler which implements
- * HandleEvent().
+ * the required OnEventHandler*() methods.
* @param eh An event handling object to add
* @param event_mask The initial event mask for the object
*/
/** Returns the number of file descriptors reported by the system this program may use
* when it was started.
- * @return If positive, the number of file descriptors that the system reported that we
- * may use. Otherwise (<= 0) this number could not be determined.
+ * @return If non-zero the number of file descriptors that the system reported that we
+ * may use.
*/
- static int GetMaxFds() { return MAX_DESCRIPTORS; }
+ static size_t GetMaxFds() { return MaxSetSize; }
/** Returns the number of file descriptors being queried
* @return The set size
* this doesn't wait long, only a couple of milliseconds. It returns the
* number of events which occurred during this call. This method will
* dispatch events to their handlers by calling their
- * EventHandler::HandleEvent() methods with the necessary EventType
- * value.
+ * EventHandler::OnEventHandler*() methods.
* @return The number of events which have occured.
*/
static int DispatchEvents();
* @param buf The buffer in which the data that is sent is stored.
* @param len The size of the buffer.
* @param flags A flag value that controls the sending of the data.
- * @param to The remote IP address and port.
- * @param tolen The size of the to parameter.
+ * @param address The remote IP address and port.
* @return This method should return exactly the same values as the system call it emulates.
*/
- static int SendTo(EventHandler* fd, const void *buf, size_t len, int flags, const sockaddr *to, socklen_t tolen);
+ static int SendTo(EventHandler* fd, const void* buf, size_t len, int flags, const irc::sockets::sockaddrs& address);
/** Abstraction for BSD sockets connect(2).
* This function should emulate its namesake system call exactly.
* @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
- * @param serv_addr The server IP address and port.
- * @param addrlen The size of the sockaddr parameter.
+ * @param address The server IP address and port.
* @return This method should return exactly the same values as the system call it emulates.
*/
- static int Connect(EventHandler* fd, const sockaddr *serv_addr, socklen_t addrlen);
+ static int Connect(EventHandler* fd, const irc::sockets::sockaddrs& address);
/** Make a file descriptor blocking.
* @param fd a file descriptor to set to blocking mode