X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=include%2Fsocketengine.h;h=c0026bfc6f2513335b0af7ba3853a12d017cff6b;hb=6c4a6b1753926f7de2cc210bf25d1b3c87c181e9;hp=305d389d4bac610e33dd83789b99c95afd7d63ae;hpb=efe77ba63b1e519fc4d563bd9b599277c4bd96e5;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/include/socketengine.h b/include/socketengine.h index 305d389d4..c0026bfc6 100644 --- a/include/socketengine.h +++ b/include/socketengine.h @@ -29,22 +29,13 @@ #include "socket.h" #include "base.h" -/** Types of event an EventHandler may receive. - * EVENT_READ is a readable file descriptor, - * and EVENT_WRITE is a writeable file descriptor. - * EVENT_ERROR can always occur, and indicates - * a write error or read error on the socket, - * e.g. EOF condition or broken pipe. - */ -enum EventType -{ - /** Read event */ - EVENT_READ = 0, - /** Write event */ - EVENT_WRITE = 1, - /** Error event */ - EVENT_ERROR = 2 -}; +#ifndef _WIN32 +#include +#endif + +#ifndef IOV_MAX +#define IOV_MAX 1024 +#endif /** * Event mask for SocketEngine events @@ -93,7 +84,7 @@ enum EventMask * 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 @@ -107,7 +98,7 @@ enum EventMask */ 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, @@ -115,17 +106,17 @@ enum EventMask 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 @@ -134,7 +125,7 @@ enum EventMask */ 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, @@ -145,17 +136,14 @@ enum EventMask /** 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. @@ -199,16 +187,20 @@ class CoreExport EventHandler : public classbase */ virtual ~EventHandler() {} - /** Process an I/O event. - * You MUST implement this function in your derived - * class, and it will be called whenever read or write - * events are received. - * @param et either one of EVENT_READ for read events, - * EVENT_WRITE for write events and EVENT_ERROR for - * error events. - * @param errornum The error code which goes with an EVENT_ERROR. + /** Called by the socket engine in case of a read event */ - virtual void HandleEvent(EventType et, int errornum = 0) = 0; + virtual void OnEventHandlerRead() = 0; + + /** Called by the socket engine in case of a write event. + * The default implementation does nothing. + */ + virtual void OnEventHandlerWrite(); + + /** Called by the socket engine in case of an error event. + * The default implementation does nothing. + * @param errornum Error code + */ + virtual void OnEventHandlerError(int errornum); friend class SocketEngine; }; @@ -306,6 +298,12 @@ class CoreExport SocketEngine } public: +#ifndef _WIN32 + typedef iovec IOVector; +#else + typedef WindowsIOVec IOVector; +#endif + /** Constructor. * The constructor transparently initializes * the socket engine which the ircd is using. @@ -327,7 +325,7 @@ public: /** 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 */ @@ -346,8 +344,10 @@ public: */ static void ChangeEventMask(EventHandler* eh, int event_mask); - /** Returns the highest file descriptor you may store in the socket engine - * @return The maximum fd value + /** 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. */ static int GetMaxFds() { return MAX_DESCRIPTORS; } @@ -384,8 +384,7 @@ public: * 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(); @@ -409,12 +408,11 @@ public: */ static int Accept(EventHandler* fd, sockaddr *addr, socklen_t *addrlen); - /** Abstraction for BSD sockets close(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. - * @return This method should return exactly the same values as the system call it emulates. + /** Close the underlying fd of an event handler, remove it from the socket engine and set the fd to -1. + * @param eh The EventHandler to close. + * @return 0 on success, a negative value on error */ - static int Close(EventHandler* fd); + static int Close(EventHandler* eh); /** Abstraction for BSD sockets close(2). * This function should emulate its namesake system call exactly. @@ -433,6 +431,27 @@ public: */ static int Send(EventHandler* fd, const void *buf, size_t len, int flags); + /** Abstraction for vector write function writev(). + * This function should emulate its namesake system call exactly. + * @param fd EventHandler to send data with + * @param iov Array of IOVectors containing the buffers to send and their lengths in the platform's + * native format. + * @param count Number of elements in iov. + * @return This method should return exactly the same values as the system call it emulates. + */ + static int WriteV(EventHandler* fd, const IOVector* iov, int count); + +#ifdef _WIN32 + /** Abstraction for vector write function writev() that accepts a POSIX format iovec. + * This function should emulate its namesake system call exactly. + * @param fd EventHandler to send data with + * @param iov Array of iovecs containing the buffers to send and their lengths in POSIX format. + * @param count Number of elements in iov. + * @return This method should return exactly the same values as the system call it emulates. + */ + static int WriteV(EventHandler* fd, const iovec* iov, int count); +#endif + /** Abstraction for BSD sockets recv(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.