| OLD | NEW |
| (Empty) |
| 1 import traceback | |
| 2 | |
| 3 cdef class PyCFSocket | |
| 4 | |
| 5 cdef void socketCallBack(CFSocketRef s, CFSocketCallBackType _type, CFDataRef ad
dress, void *data, void *info): | |
| 6 cdef PyCFSocket socket | |
| 7 cdef int res | |
| 8 cdef int mask | |
| 9 socket = (<PyCFSocket>info) | |
| 10 #print "fileno = %r" % (socket.fileno,) | |
| 11 try: | |
| 12 if _type == kCFSocketReadCallBack: | |
| 13 if socket.readcallback: | |
| 14 socket.readcallback() | |
| 15 elif _type == kCFSocketWriteCallBack: | |
| 16 if socket.writecallback: | |
| 17 socket.writecallback() | |
| 18 elif _type == kCFSocketConnectCallBack: | |
| 19 if data == NULL: | |
| 20 res = 0 | |
| 21 else: | |
| 22 res = (<int*>data)[0] | |
| 23 if socket.connectcallback: | |
| 24 socket.connectcallback(res) | |
| 25 except: | |
| 26 traceback.print_exc() | |
| 27 | |
| 28 cdef void gilSocketCallBack(CFSocketRef s, CFSocketCallBackType _type, CFDataRef
address, void *data, void *info): | |
| 29 cdef PyGILState_STATE gil | |
| 30 gil = PyGILState_Ensure() | |
| 31 socketCallBack(s, _type, address, data, info) | |
| 32 PyGILState_Release(gil) | |
| 33 | |
| 34 cdef class PyCFSocket: | |
| 35 cdef public object readcallback | |
| 36 cdef public object writecallback | |
| 37 cdef public object connectcallback | |
| 38 cdef public object reading | |
| 39 cdef public object writing | |
| 40 cdef CFSocketRef cf | |
| 41 cdef CFRunLoopSourceRef source | |
| 42 cdef readonly CFSocketNativeHandle fileno | |
| 43 cdef CFSocketContext context | |
| 44 | |
| 45 def __new__(self, CFSocketNativeHandle fileno, readcallback=None, writecallb
ack=None, connectcallback=None): | |
| 46 #print "new socket %r" % (fileno,) | |
| 47 self.fileno = fileno | |
| 48 self.readcallback = readcallback | |
| 49 self.writecallback = writecallback | |
| 50 self.connectcallback = connectcallback | |
| 51 self.context.version = 0 | |
| 52 self.context.info = <void *>self | |
| 53 self.context.retain = NULL | |
| 54 self.context.release = NULL | |
| 55 self.context.copyDescription = NULL | |
| 56 self.reading = False | |
| 57 self.writing = False | |
| 58 self.cf = CFSocketCreateWithNative(kCFAllocatorDefault, fileno, kCFSocke
tConnectCallBack | kCFSocketReadCallBack | kCFSocketWriteCallBack, <CFSocketCall
Back>&gilSocketCallBack, &self.context) | |
| 59 if self.cf == NULL: | |
| 60 raise ValueError("Invalid Socket") | |
| 61 self.source = CFSocketCreateRunLoopSource(kCFAllocatorDefault, self.cf,
10000) | |
| 62 if self.source == NULL: | |
| 63 raise ValueError("Couldn't create runloop source") | |
| 64 #print "made new socket" | |
| 65 | |
| 66 def update(self): | |
| 67 cdef int mask | |
| 68 cdef int offmask | |
| 69 cdef int automask | |
| 70 mask = kCFSocketConnectCallBack | kCFSocketAcceptCallBack | |
| 71 offmask = 0 | |
| 72 automask = kCFSocketAutomaticallyReenableAcceptCallBack | |
| 73 if self.reading: | |
| 74 mask = mask | kCFSocketReadCallBack | |
| 75 automask = automask | kCFSocketAutomaticallyReenableReadCallBack | |
| 76 else: | |
| 77 offmask = offmask | kCFSocketReadCallBack | |
| 78 if self.writing: | |
| 79 mask = mask | kCFSocketWriteCallBack | |
| 80 automask = automask | kCFSocketAutomaticallyReenableWriteCallBack | |
| 81 else: | |
| 82 offmask = offmask | kCFSocketWriteCallBack | |
| 83 CFSocketDisableCallBacks(self.cf, offmask) | |
| 84 CFSocketEnableCallBacks(self.cf, mask) | |
| 85 CFSocketSetSocketFlags(self.cf, automask) | |
| 86 | |
| 87 | |
| 88 def startReading(self): | |
| 89 self.reading = True | |
| 90 self.update() | |
| 91 | |
| 92 def stopReading(self): | |
| 93 self.reading = False | |
| 94 self.update() | |
| 95 | |
| 96 def startWriting(self): | |
| 97 self.writing = True | |
| 98 self.update() | |
| 99 | |
| 100 def stopWriting(self): | |
| 101 self.writing = False | |
| 102 self.update() | |
| 103 | |
| 104 def __dealloc__(self): | |
| 105 #print "PyCFSocket(%r).__dealloc__()" % (self.fileno,) | |
| 106 if self.source != NULL: | |
| 107 CFRelease(self.source) | |
| 108 if self.cf != NULL: | |
| 109 CFSocketInvalidate(self.cf) | |
| 110 CFRelease(self.cf) | |
| 111 #print "__dealloc__()" | |
| OLD | NEW |