diff options
Diffstat (limited to 'python/gevent/libev/libev_vfd.h')
-rw-r--r-- | python/gevent/libev/libev_vfd.h | 225 |
1 files changed, 0 insertions, 225 deletions
diff --git a/python/gevent/libev/libev_vfd.h b/python/gevent/libev/libev_vfd.h deleted file mode 100644 index ff30fd8..0000000 --- a/python/gevent/libev/libev_vfd.h +++ /dev/null @@ -1,225 +0,0 @@ -#ifdef _WIN32 -/* see discussion in the libuv directory: this is a SOCKET which is a - HANDLE which is a PVOID (even though they're really small ints), - and CPython and PyPy return that SOCKET cast to an int from - fileno() -*/ -typedef intptr_t vfd_socket_t; -#define vfd_socket_object PyLong_FromLongLong - -#ifdef LIBEV_EMBED -/* - * If libev on win32 is embedded, then we can use an - * arbitrary mapping between integer fds and OS - * handles. Then by defining special macros libev - * will use our functions. - */ - -#define WIN32_LEAN_AND_MEAN -#include <winsock2.h> -#include <windows.h> - -typedef struct vfd_entry_t -{ - vfd_socket_t handle; /* OS handle, i.e. SOCKET */ - int count; /* Reference count, 0 if free */ - int next; /* Next free fd, -1 if last */ -} vfd_entry; - -#define VFD_INCREMENT 128 -static int vfd_num = 0; /* num allocated fds */ -static int vfd_max = 0; /* max allocated fds */ -static int vfd_next = -1; /* next free fd for reuse */ -static PyObject* vfd_map = NULL; /* map OS handle -> virtual fd */ -static vfd_entry* vfd_entries = NULL; /* list of virtual fd entries */ - -#ifdef WITH_THREAD -static CRITICAL_SECTION* volatile vfd_lock = NULL; -static CRITICAL_SECTION* vfd_make_lock() -{ - if (vfd_lock == NULL) { - /* must use malloc and not PyMem_Malloc here */ - CRITICAL_SECTION* lock = malloc(sizeof(CRITICAL_SECTION)); - InitializeCriticalSection(lock); - if (InterlockedCompareExchangePointer(&vfd_lock, lock, NULL) != NULL) { - /* another thread initialized lock first */ - DeleteCriticalSection(lock); - free(lock); - } - } - return vfd_lock; -} -#define VFD_LOCK_ENTER EnterCriticalSection(vfd_make_lock()) -#define VFD_LOCK_LEAVE LeaveCriticalSection(vfd_lock) -#define VFD_GIL_DECLARE PyGILState_STATE ___save -#define VFD_GIL_ENSURE ___save = PyGILState_Ensure() -#define VFD_GIL_RELEASE PyGILState_Release(___save) -#else /* ! WITH_THREAD */ -#define VFD_LOCK_ENTER -#define VFD_LOCK_LEAVE -#define VFD_GIL_DECLARE -#define VFD_GIL_ENSURE -#define VFD_GIL_RELEASE -#endif /*_WITH_THREAD */ - -/* - * Given a virtual fd returns an OS handle or -1 - * This function is speed critical, so it cannot use GIL - */ -static vfd_socket_t vfd_get(int fd) -{ - vfd_socket_t handle = -1; - VFD_LOCK_ENTER; - if (vfd_entries != NULL && fd >= 0 && fd < vfd_num) - handle = vfd_entries[fd].handle; - VFD_LOCK_LEAVE; - return handle; -} - -#define EV_FD_TO_WIN32_HANDLE(fd) vfd_get((fd)) - -/* - * Given an OS handle finds or allocates a virtual fd - * Returns -1 on failure and sets Python exception if pyexc is non-zero - */ -static int vfd_open_(vfd_socket_t handle, int pyexc) -{ - VFD_GIL_DECLARE; - int fd = -1; - unsigned long arg; - PyObject* key = NULL; - PyObject* value; - - if (!pyexc) { - VFD_GIL_ENSURE; - } - if (ioctlsocket(handle, FIONREAD, &arg) != 0) { - if (pyexc) - PyErr_Format(PyExc_IOError, -#ifdef _WIN64 - "%lld is not a socket (files are not supported)", -#else - "%ld is not a socket (files are not supported)", -#endif - handle); - goto done; - } - if (vfd_map == NULL) { - vfd_map = PyDict_New(); - if (vfd_map == NULL) - goto done; - } - key = vfd_socket_object(handle); - /* check if it's already in the dict */ - value = PyDict_GetItem(vfd_map, key); - if (value != NULL) { - /* is it safe to use PyInt_AS_LONG(value) here? */ - fd = PyInt_AsLong(value); - if (fd >= 0) { - ++vfd_entries[fd].count; - goto done; - } - } - /* use the free entry, if available */ - if (vfd_next >= 0) { - fd = vfd_next; - vfd_next = vfd_entries[fd].next; - VFD_LOCK_ENTER; - goto allocated; - } - /* check if it would be out of bounds */ - if (vfd_num >= FD_SETSIZE) { - /* libev's select doesn't support more that FD_SETSIZE fds */ - if (pyexc) - PyErr_Format(PyExc_IOError, "cannot watch more than %d sockets", (int)FD_SETSIZE); - goto done; - } - /* allocate more space if needed */ - VFD_LOCK_ENTER; - if (vfd_num >= vfd_max) { - int newsize = vfd_max + VFD_INCREMENT; - vfd_entry* entries = PyMem_Realloc(vfd_entries, sizeof(vfd_entry) * newsize); - if (entries == NULL) { - VFD_LOCK_LEAVE; - if (pyexc) - PyErr_NoMemory(); - goto done; - } - vfd_entries = entries; - vfd_max = newsize; - } - fd = vfd_num++; -allocated: - /* vfd_lock must be acquired when entering here */ - vfd_entries[fd].handle = handle; - vfd_entries[fd].count = 1; - VFD_LOCK_LEAVE; - value = PyInt_FromLong(fd); - PyDict_SetItem(vfd_map, key, value); - Py_DECREF(value); -done: - Py_XDECREF(key); - if (!pyexc) { - VFD_GIL_RELEASE; - } - return fd; -} - -#define vfd_open(fd) vfd_open_((fd), 1) -#define EV_WIN32_HANDLE_TO_FD(handle) vfd_open_((handle), 0) - -static void vfd_free_(int fd, int needclose) -{ - VFD_GIL_DECLARE; - PyObject* key; - - if (needclose) { - VFD_GIL_ENSURE; - } - if (fd < 0 || fd >= vfd_num) - goto done; /* out of bounds */ - if (vfd_entries[fd].count <= 0) - goto done; /* free entry, ignore */ - if (!--vfd_entries[fd].count) { - /* fd has just been freed */ - vfd_socket_t handle = vfd_entries[fd].handle; - vfd_entries[fd].handle = -1; - vfd_entries[fd].next = vfd_next; - vfd_next = fd; - if (needclose) - closesocket(handle); - /* vfd_map is assumed to be != NULL */ - key = vfd_socket_object(handle); - PyDict_DelItem(vfd_map, key); - Py_DECREF(key); - } -done: - if (needclose) { - VFD_GIL_RELEASE; - } -} - -#define vfd_free(fd) vfd_free_((fd), 0) -#define EV_WIN32_CLOSE_FD(fd) vfd_free_((fd), 1) - -#else /* !LIBEV_EMBED */ -/* - * If libev on win32 is not embedded in gevent, then - * the only way to map vfds is to use the default of - * using runtime fds in libev. Note that it will leak - * fds, because there's no way of closing them safely - */ -#define vfd_get(fd) _get_osfhandle((fd)) -#define vfd_open(fd) _open_osfhandle((fd), 0) -#define vfd_free(fd) -#endif /* LIBEV_EMBED */ - -#else /* !_WIN32 */ -/* - * On non-win32 platforms vfd_* are noop macros - */ -typedef int vfd_socket_t; -#define vfd_get(fd) (fd) -#define vfd_open(fd) (fd) -#define vfd_free(fd) -#endif /* _WIN32 */ |