]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - include/socketengine.h
Replace SocketEngine::GetName() with INSPIRCD_SOCKETENGINE_NAME define
[user/henk/code/inspircd.git] / include / socketengine.h
index b790f6d77596b389bab0862b1b35aa8754ae0797..a2179d951e7ee5726d3dda5617bb803380397b41 100644 (file)
  */
 
 
-#ifndef SOCKETENGINE_H
-#define SOCKETENGINE_H
+#pragma once
 
 #include <vector>
 #include <string>
 #include <map>
-#include "inspircd_config.h"
+#include "config.h"
 #include "socket.h"
 #include "base.h"
 
@@ -128,7 +127,7 @@ enum EventMask
        /** Add a trial write. During the next DispatchEvents invocation, this
         * will call HandleEvent with EVENT_WRITE unless writes are known to be
         * blocking.
-        * 
+        *
         * This could be used to group several writes together into a single
         * send() syscall, or to ensure that writes are blocking when attempting
         * to use FD_WANT_FAST_WRITE.
@@ -137,7 +136,7 @@ enum EventMask
        /** Assert that writes are known to block. This cancels FD_ADD_TRIAL_WRITE.
         * Reset by SE before running EVENT_WRITE
         */
-       FD_WRITE_WILL_BLOCK = 0x8000, 
+       FD_WRITE_WILL_BLOCK = 0x8000,
 
        /** Mask for trial read/trial write */
        FD_TRIAL_NOTE_MASK = 0x5000
@@ -231,13 +230,14 @@ class CoreExport EventHandler : public classbase
  */
 class CoreExport SocketEngine
 {
+       /** Reference table, contains all current handlers
+        **/
+       std::vector<EventHandler*> ref;
+
  protected:
        /** Current number of descriptors in the engine
         */
-       int CurrentSetSize;
-       /** Reference table, contains all current handlers
-        */
-       EventHandler** ref;
+       size_t CurrentSetSize;
        /** List of handlers that want a trial read/write
         */
        std::set<int> trials;
@@ -252,6 +252,18 @@ class CoreExport SocketEngine
 
        virtual void OnSetEvent(EventHandler* eh, int old_mask, int new_mask) = 0;
        void SetEventMask(EventHandler* eh, int value);
+
+       /** Add an event handler to the base socket engine. AddFd(EventHandler*, int) should call this.
+        */
+       bool AddFd(EventHandler* eh);
+
+       template <typename T>
+       void ResizeDouble(std::vector<T>& vect)
+       {
+               if (CurrentSetSize > vect.size())
+                       vect.resize(vect.size() * 2);
+       }
+
 public:
 
        unsigned long TotalEvents;
@@ -305,7 +317,7 @@ public:
        /** Returns the number of file descriptors being queried
         * @return The set size
         */
-       inline int GetUsedFds() const { return CurrentSetSize; }
+       inline size_t GetUsedFds() const { return CurrentSetSize; }
 
        /** Delete an event handler from the engine.
         * This function call deletes an EventHandler
@@ -315,7 +327,7 @@ public:
         * required you must do this yourself.
         * @param eh The event handler object to remove
         */
-       virtual void DelFd(EventHandler* eh) = 0;
+       virtual void DelFd(EventHandler* eh);
 
        /** Returns true if a file descriptor exists in
         * the socket engine's list.
@@ -346,12 +358,6 @@ public:
         */
        virtual void DispatchTrialWrites();
 
-       /** Returns the socket engines name.  This returns the name of the
-        * engine for use in /VERSION responses.
-        * @return The socket engine name
-        */
-       virtual std::string GetName() = 0;
-
        /** Returns true if the file descriptors in the given event handler are
         * within sensible ranges which can be handled by the socket engine.
         */
@@ -364,21 +370,21 @@ public:
         * @param addrlen The size of the sockaddr parameter.
         * @return This method should return exactly the same values as the system call it emulates.
         */
-       int Accept(EventHandler* fd, sockaddr *addr, socklen_t *addrlen);
+       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.
         */
-       int Close(EventHandler* fd);
+       static int Close(EventHandler* fd);
 
        /** Abstraction for BSD sockets close(2).
         * This function should emulate its namesake system call exactly.
         * This function should emulate its namesake system call exactly.
         * @return This method should return exactly the same values as the system call it emulates.
         */
-       int Close(int fd);
+       static int Close(int fd);
 
        /** Abstraction for BSD sockets send(2).
         * This function should emulate its namesake system call exactly.
@@ -418,7 +424,7 @@ public:
         * @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 to The remote IP address and port.
         * @param tolen The size of the to parameter.
         * @return This method should return exactly the same values as the system call it emulates.
         */
@@ -431,19 +437,19 @@ public:
         * @param addrlen The size of the sockaddr parameter.
         * @return This method should return exactly the same values as the system call it emulates.
         */
-       int Connect(EventHandler* fd, const sockaddr *serv_addr, socklen_t addrlen);
+       static int Connect(EventHandler* fd, const sockaddr *serv_addr, socklen_t addrlen);
 
        /** Make a file descriptor blocking.
         * @param fd a file descriptor to set to blocking mode
         * @return 0 on success, -1 on failure, errno is set appropriately.
         */
-       int Blocking(int fd);
+       static int Blocking(int fd);
 
        /** Make a file descriptor nonblocking.
         * @param fd A file descriptor to set to nonblocking mode
         * @return 0 on success, -1 on failure, errno is set appropriately.
         */
-       int NonBlocking(int fd);
+       static int NonBlocking(int fd);
 
        /** Abstraction for BSD sockets shutdown(2).
         * This function should emulate its namesake system call exactly.
@@ -451,29 +457,29 @@ public:
         * @param how What part of the socket to shut down
         * @return This method should return exactly the same values as the system call it emulates.
         */
-       int Shutdown(EventHandler* fd, int how);
+       static int Shutdown(EventHandler* fd, int how);
 
        /** Abstraction for BSD sockets shutdown(2).
         * This function should emulate its namesake system call exactly.
         * @return This method should return exactly the same values as the system call it emulates.
         */
-       int Shutdown(int fd, int how);
+       static int Shutdown(int fd, int how);
 
        /** Abstraction for BSD sockets bind(2).
         * This function should emulate its namesake system call exactly.
         * @return This method should return exactly the same values as the system call it emulates.
         */
-       int Bind(int fd, const irc::sockets::sockaddrs& addr);
+       static int Bind(int fd, const irc::sockets::sockaddrs& addr);
 
        /** Abstraction for BSD sockets listen(2).
         * This function should emulate its namesake system call exactly.
         * @return This method should return exactly the same values as the system call it emulates.
         */
-       int Listen(int sockfd, int backlog);
+       static int Listen(int sockfd, int backlog);
 
        /** Set SO_REUSEADDR and SO_LINGER on this file descriptor
         */
-       void SetReuse(int sockfd);
+       static void SetReuse(int sockfd);
 
        /** This function is called immediately after fork().
         * Some socket engines (notably kqueue) cannot have their
@@ -489,9 +495,32 @@ public:
        /** Get data transfer statistics, kilobits per second in and out and total.
         */
        void GetStats(float &kbitpersec_in, float &kbitpersec_out, float &kbitpersec_total);
+
+       /** Should we ignore the error in errno?
+        * Checks EAGAIN and WSAEWOULDBLOCK
+        */
+       static bool IgnoreError();
+
+       /** Return the last socket related error. strrerror(errno) on *nix
+        */
+       static std::string LastError();
+
+       /** Returns the error for the given error num, strerror(errnum) on *nix
+        */
+       static std::string GetError(int errnum);
 };
 
-SocketEngine* CreateSocketEngine();
+inline bool SocketEngine::IgnoreError()
+{
+       if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
+               return true;
 
+#ifdef _WIN32
+       if (WSAGetLastError() == WSAEWOULDBLOCK)
+               return true;
 #endif
 
+       return false;
+}
+
+SocketEngine* CreateSocketEngine();