Author: ArcRiley Date: 2009-02-21 12:31:52 -0500 (Sat, 21 Feb 2009) New Revision: 1514
Modified: trunk/concordance/include/concordance.sockets.h trunk/concordance/src/sockets/Client.c trunk/concordance/src/sockets/Socket.c trunk/concordance/src/sockets/__init__.c Log: polished type inheritance Modified: trunk/concordance/include/concordance.sockets.h =================================================================== --- trunk/concordance/include/concordance.sockets.h 2009-02-12 19:42:06 UTC (rev 1513) +++ trunk/concordance/include/concordance.sockets.h 2009-02-21 17:31:52 UTC (rev 1514) @@ -26,10 +26,12 @@ /* concordance.sockets.Socket definition */ -PyTypeObject socketsSocket_Type; -PyObject* socketsSocket_new (PyTypeObject*, PyObject*, PyObject*); -void socketsSocket_dealloc (PyObject*); typedef struct { + PyTypeObject base; + gboolean (* _listenNew ) (GIOChannel*, GIOCondition, gpointer); +} socketsSocket_TypeObject; +extern socketsSocket_TypeObject socketsSocket_Type; +typedef struct { PyObject_HEAD PyObject* module; /* reference to our own module */ GMainContext* context; /* Concordance's Glib context */ @@ -41,10 +43,12 @@ /* concordance.sockets.Client definition */ -PyTypeObject socketsClient_Type; -PyObject* socketsClient_new (PyTypeObject*, PyObject*, PyObject*); -void socketsClient_dealloc (PyObject*); typedef struct { + PyTypeObject base; + gboolean (* _listenNew ) (GIOChannel*, GIOCondition, gpointer); +} socketsClient_TypeObject; +extern socketsClient_TypeObject socketsClient_Type; +typedef struct { PyObject_HEAD PyObject* module; /* reference to our own module */ GMainContext* context; /* Concordance's Glib context */ Modified: trunk/concordance/src/sockets/Client.c =================================================================== --- trunk/concordance/src/sockets/Client.c 2009-02-12 19:42:06 UTC (rev 1513) +++ trunk/concordance/src/sockets/Client.c 2009-02-21 17:31:52 UTC (rev 1514) @@ -25,14 +25,45 @@ cdef class Socket : \*/ static char socketsClient_Doc[] = "Test"; + static gboolean + _listenNew(GIOChannel* channel, GIOCondition condition, gpointer s) { /*\ + cdef : \*/ + socketsSocket_Object* self = (socketsSocket_Object*) s; + gint socket; + struct sockaddr addr; + guint addrlen = sizeof(addr); - PyObject* - socketsClient_new(PyTypeObject* type, PyObject* args, PyObject* kwds) { /*\ + /* accept new connection, return if we fail to connect + + int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); + */ + if ((socket = accept(g_io_channel_unix_get_fd(channel), + &addr, &addrlen))<0) { + /* return true so GMainLoop will continue watching this channel */ + return TRUE; + } + + /* this is a generic Socket object, just close incoming connections */ + close(socket); + + /* return true so GMainLoop will continue watching this channel */ + return TRUE; + } + + /* + # + ########################################################################### + # + # object constructor - deconstructor + # */ + + static PyObject* + _new(PyTypeObject* type, PyObject* args, PyObject* kwds) { /*\ cdef : \*/ socketsClient_Object* self; /* first inherit base type */ - self = (socketsClient_Object*) socketsSocket_new(type, args, kwds); + self = (socketsClient_Object*) type->tp_base->tp_new(type, args, kwds); if (!self) return NULL; @@ -60,38 +91,15 @@ } - static int - socketsClient_init(PyObject* s, PyObject* args, PyObject* kwds) { /*\ + static void + _dealloc(PyObject* s) { /*\ cdef : \*/ socketsClient_Object* self = (socketsClient_Object*) s; - - return 0; - } - - void - socketsClient_dealloc(PyObject* s) { /*\ - cdef : \*/ - socketsClient_Object* self = (socketsClient_Object*) s; - /* lastly dealloc base type */ - socketsSocket_dealloc(s); + s->ob_type->tp_base->tp_dealloc(s); } - - static PyObject* - socketsClient_getattro(socketsClient_Object* self, PyObject* key) { - return PyObject_GenericGetAttr((PyObject*) self, key); - } - - - static int - socketsClient_setattro(socketsClient_Object* self, PyObject* key, - PyObject* value) { - return PyObject_GenericSetAttr((PyObject*) self, key, value); - } - - /* # ########################################################################### @@ -104,15 +112,15 @@ }; - PyTypeObject socketsClient_Type = { + socketsClient_TypeObject socketsClient_Type = { { PyVarObject_HEAD_INIT(NULL, 0) "concordance.sockets.Client", /*tp_name*/ sizeof(socketsClient_Object), /*tp_basicsize*/ 0, /*tp_itemsize*/ - (destructor) socketsClient_dealloc, /*tp_dealloc*/ + (destructor) _dealloc, /*tp_dealloc*/ 0, /*tp_print*/ - (getattrfunc) 0, /*tp_getattr*/ - (setattrfunc) 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ @@ -121,8 +129,8 @@ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ - (getattrofunc) socketsClient_getattro, /*tp_getattro*/ - (setattrofunc) socketsClient_setattro, /*tp_setattro*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ socketsClient_Doc, /*tp_doc*/ @@ -135,14 +143,17 @@ socketsClient_Methods, /*tp_methods*/ 0, /*tp_members*/ 0, /*tp_getset*/ - &socketsSocket_Type, /*tp_base*/ + (struct _typeobject*) &socketsSocket_Type, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ - socketsClient_init, /*tp_init*/ + 0, /*tp_init*/ 0, /*tp_alloc*/ - socketsClient_new, /*tp_new*/ + _new, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ + }, + /* cdef classes */ + _listenNew, }; Modified: trunk/concordance/src/sockets/Socket.c =================================================================== --- trunk/concordance/src/sockets/Socket.c 2009-02-12 19:42:06 UTC (rev 1513) +++ trunk/concordance/src/sockets/Socket.c 2009-02-21 17:31:52 UTC (rev 1514) @@ -25,59 +25,14 @@ cdef class Socket : \*/ static char socketsSocket_Doc[] = "Test"; - - PyObject* - socketsSocket_new(PyTypeObject* type, PyObject* args, PyObject* kwds) { /*\ - cdef : \*/ - socketsSocket_Object* self; - - /* first inherit base type */ - self = (socketsSocket_Object*) PyType_GenericNew(type, args, kwds); - if (!self) - return NULL; - - /* set addr, port, and sock to default values - - 0.0.0.0 = listen to every available interface - port is overridden by child class - */ - self->addr = "0.0.0.0"; - self->port = 0; - self->sock = -1; - - /* Get a reference to our local module - - This is to keep our module alive as long as this instance. - - PyObject* PyImport_ImportModule (const char *name); - */ - self->module = PyImport_ImportModule("concordance.sockets"); - - /* Get context from global state - - I'm sorry for this. Here's the natural language for this block: - 1) get the state of sockets module - a PyObject** to concordance._core - 2) dereference the PyObject** to PyObject* - 3) get the state of _core - a concordGlobals** - 4) dereference concordGlobals** to concordGlobals* - 5) copy the GMainContext* context from the struct to self->context - - void* PyModule_GetState (PyObject*); - */ - self->context = (*(concordGlobals**) PyModule_GetState( - *(PyObject**) PyModule_GetState(self->module)))->context; - - /* return self */ - return (PyObject*) self; - } - - static int - socketsSocket_init(PyObject* s, PyObject* args, PyObject* kwds) { /*\ + _init(PyObject* s, PyObject* args, PyObject* kwds) { /*\ cdef : \*/ socketsSocket_Object* self = (socketsSocket_Object*) s; int ret; struct addrinfo* resinfo = NULL; + GSource* source; + static char* kwlist[] = {"bind", 0}; /* parse arguments and keywords @@ -101,7 +56,7 @@ used as the function name in error messages (the “associated value” of the exception that PyArg_ParseTuple raises). */ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|sH:Socket", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|(sH):Socket", kwlist, &self->addr, &self->port)) return -1; @@ -188,17 +143,38 @@ if (bind(self->sock, resinfo->ai_addr, resinfo->ai_addrlen) == 0 && listen(self->sock, 16) == 0 ) { - /* create channel and add it to our context watchlist + /* create a new channel using an OS-dependent function - GIOChannel* concordAddSocket (gint fd, - GIOCondition condition, - GSourceFunc callback, - gpointer data, - GMainContext* context); + GIOChannel* g_io_channel_win32_new_fd (gint fd); + GIOChannel* g_io_channel_unix_new (gint fd); */ - self->chan = concordAddSocket(self->sock, G_IO_IN, - (GSourceFunc) concordCore_listenNew, - (gpointer) self, self->context); + #ifdef MS_WINDOWS + self->chan = g_io_channel_win32_new_socket(self->sock); + #else + self->chan = g_io_channel_unix_new(self->sock); + #endif + + /* add a channel to our context watch + + Note that this function is a replacement for g_io_add_watch() which + uses our own context rather than the default context. + + GSource* g_io_create_watch (GIOChannel *channel, + GIOCondition condition); + void g_source_set_callback (GSource *source, + GSourceFunc func, + gpointer data, + GDestroyNotify notify); + guint g_source_attach (GSource *source, + GMainContext *context); + */ + source = g_io_create_watch(self->chan, G_IO_IN); + g_source_set_callback(source, (GSourceFunc) + ((socketsSocket_TypeObject*) s->ob_type)-> + _listenNew, + (gpointer) self, NULL); + g_source_attach(source, self->context); + g_source_unref(source); ret = 0; } else { @@ -222,37 +198,113 @@ } - void - socketsSocket_dealloc(PyObject* s) { /*\ + static PyObject* + _getattro(PyObject* self, PyObject* key) { + return PyObject_GenericGetAttr((PyObject*) self, key); + } + + + static int + _setattro(PyObject* self, PyObject* key, PyObject* value) { + return PyObject_GenericSetAttr((PyObject*) self, key, value); + } + + static gboolean + _listenNew(GIOChannel* channel, GIOCondition condition, gpointer s) { /*\ cdef : \*/ socketsSocket_Object* self = (socketsSocket_Object*) s; + gint socket; + struct sockaddr addr; + guint addrlen = sizeof(addr); - /* close the socket if open */ - if (self->sock > -1) - close(self->sock); + /* accept new connection, return if we fail to connect - /* decref our module handle, which may in-turn decref _core */ - if (self->module) - Py_DECREF(self->module); + int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); + */ + if ((socket = accept(g_io_channel_unix_get_fd(channel), + &addr, &addrlen))<0) { + /* return true so GMainLoop will continue watching this channel */ + return TRUE; + } - /* lastly dealloc base type */ - PyObject_Del(s); + /* this is a generic Socket object, just close incoming connections */ + close(socket); + + /* return true so GMainLoop will continue watching this channel */ + return TRUE; } + /* + # + ########################################################################### + # + # object constructor - deconstructor + # */ + static PyObject* - socketsSocket_getattro(socketsSocket_Object* self, PyObject* key) { - return PyObject_GenericGetAttr((PyObject*) self, key); + _new(PyTypeObject* type, PyObject* args, PyObject* kwds) { /*\ + cdef : \*/ + socketsSocket_Object* self; + + /* first inherit base type */ + self = (socketsSocket_Object*) type->tp_base->tp_new(type, args, kwds); + if (!self) + return NULL; + + /* set addr, port, and sock to default values + + 0.0.0.0 = listen to every available interface + port is overridden by child class + */ + self->addr = "0.0.0.0"; + self->port = 0; + self->sock = -1; + + /* Get a reference to our local module + + This is to keep our module alive as long as this instance. + + PyObject* PyImport_ImportModule (const char *name); + */ + self->module = PyImport_ImportModule("concordance.sockets"); + + /* Get context from global state + + I'm sorry for this. Here's the natural language for this block: + 1) get the state of sockets module - a PyObject** to concordance._core + 2) dereference the PyObject** to PyObject* + 3) get the state of _core - a concordGlobals** + 4) dereference concordGlobals** to concordGlobals* + 5) copy the GMainContext* context from the struct to self->context + + void* PyModule_GetState (PyObject*); + */ + self->context = (*(concordGlobals**) PyModule_GetState( + *(PyObject**) PyModule_GetState(self->module)))->context; + + /* return self */ + return (PyObject*) self; } - static int - socketsSocket_setattro(socketsSocket_Object* self, PyObject* key, - PyObject* value) { - return PyObject_GenericSetAttr((PyObject*) self, key, value); - } + static void + _dealloc(PyObject* s) { /*\ + cdef : \*/ + socketsSocket_Object* self = (socketsSocket_Object*) s; + + /* close the socket if open */ + if (self->sock > -1) + close(self->sock); + + /* decref our module handle, which may in-turn decref _core */ + if (self->module) + Py_DECREF(self->module); + + /* lastly dealloc base type */ + s->ob_type->tp_base->tp_dealloc(s); + } - /* # ########################################################################### @@ -264,13 +316,12 @@ { NULL, NULL }, /* sentinel */ }; - - PyTypeObject socketsSocket_Type = { + socketsSocket_TypeObject socketsSocket_Type = { { PyVarObject_HEAD_INIT(NULL, 0) "concordance.sockets.Socket", /*tp_name*/ sizeof(socketsSocket_Object), /*tp_basicsize*/ 0, /*tp_itemsize*/ - (destructor) socketsSocket_dealloc, /*tp_dealloc*/ + (destructor) _dealloc, /*tp_dealloc*/ 0, /*tp_print*/ (getattrfunc) 0, /*tp_getattr*/ (setattrfunc) 0, /*tp_setattr*/ @@ -282,8 +333,8 @@ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ - (getattrofunc) socketsSocket_getattro, /*tp_getattro*/ - (setattrofunc) socketsSocket_setattro, /*tp_setattro*/ + _getattro, /*tp_getattro*/ + _setattro, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ socketsSocket_Doc, /*tp_doc*/ @@ -301,9 +352,14 @@ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ - socketsSocket_init, /*tp_init*/ + _init, /*tp_init*/ 0, /*tp_alloc*/ - (newfunc) PyType_GenericNew, /*tp_new*/ + _new, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ + }, + /* cdef classes */ + _listenNew, }; + + Modified: trunk/concordance/src/sockets/__init__.c =================================================================== --- trunk/concordance/src/sockets/__init__.c 2009-02-12 19:42:06 UTC (rev 1513) +++ trunk/concordance/src/sockets/__init__.c 2009-02-21 17:31:52 UTC (rev 1514) @@ -65,9 +65,9 @@ inherited slots from a type’s base class. Return 0 on success, or return -1 and sets an exception on error. */ - if (PyType_Ready(&socketsSocket_Type) < 0) + if (PyType_Ready((PyTypeObject*) &socketsSocket_Type) < 0) return NULL; - if (PyType_Ready(&socketsClient_Type) < 0) + if (PyType_Ready((PyTypeObject*) &socketsClient_Type) < 0) return NULL; /* Get a handle to _core or fail _______________________________________________ PySoy-SVN mailing list PySoy-SVN@pysoy.org http://www.pysoy.org/mailman/listinfo/pysoy-svn