ionel's codelog

Ctypes based iocp proactor for cogen

Sat 29 November 2008

I've finally mannaged to pull off a set of wrappers for using the raw windows iocp api using ctypes, namely wrappers for GetQueuedCompletionStatus, WSARecv, WSASend, AcceptEx, ConnectEx, TransmitFile and the whatever structs and utility calls they need.

Writing the wrappers wasn't that hard - but if you aren't careful with ctypes you are in a world of gruesome crashes and at least 2 wasted evenings (read nights) debugging why the hell some random allocation fails. Well, for a fact, I still have no idea to why do I own those to wasted nights but thank god it doesn't crash on my unittests anymore - I think I could have figured out why some missing object cleanup resulted in weird crashes if I knew some ctypes internals but eh, I don't :(

Take a look at the evil code here and here, and punish me for doing such an evil thing with ctypes *malefic laugh* =]

Here's a gem:

# signature: BOOL = SOCKET hSocket, HANDLE hFile, DWORD nNumberOfBytesToWrite, DWORD nNumberOfBytesPerSend, LPOVERLAPPED lpOverlapped,LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers, DWORD dwFlags
TransmitFileType = WINFUNCTYPE(BOOL, SOCKET, HANDLE, DWORD, DWORD, POINTER(OVERLAPPED), POINTER(TRANSMIT_FILE_BUFFERS), DWORD)

def _GetTransmitFilePtr(given_socket=None):
    from socket import socket
    bogus_sock = given_socket or socket()
    bogus_bytes = DWORD()
    TransmitFile = TransmitFileType(0)
    ret = WSAIoctl(
        bogus_sock.fileno(), SIO_GET_EXTENSION_FUNCTION_POINTER, byref(WSAID_TRANSMITFILE), sizeof(WSAID_TRANSMITFILE),
        byref(TransmitFile), sizeof(TransmitFile), byref(bogus_bytes), None, None
    )
    return TransmitFile

TransmitFile = _GetTransmitFilePtr()

So far the new proactor works pretty nice in cogen.

This entry was tagged as cogen ctypes python

blog comments powered by Disqus