handle case of empty text
[enigma2.git] / lib / base / ebase.cpp
1 #include <lib/base/ebase.h>
2
3 #include <fcntl.h>
4 #include <unistd.h>
5 #include <errno.h>
6
7 #include <lib/base/eerror.h>
8 #include <lib/base/elock.h>
9
10 eSocketNotifier::eSocketNotifier(eMainloop *context, int fd, int requested, bool startnow): context(*context), fd(fd), state(0), requested(requested)
11 {
12         if (startnow)   
13                 start();
14 }
15
16 eSocketNotifier::~eSocketNotifier()
17 {
18         stop();
19 }
20
21 void eSocketNotifier::start()
22 {
23         if (state)
24                 stop();
25
26         context.addSocketNotifier(this);
27         state=2;  // running but not in poll yet
28 }
29
30 void eSocketNotifier::stop()
31 {
32         if (state)
33                 context.removeSocketNotifier(this);
34
35         state=0;
36 }
37
38                                         // timer
39 void eTimer::start(long msek, bool singleShot)
40 {
41         if (bActive)
42                 stop();
43
44         bActive = true;
45         bSingleShot = singleShot;
46         interval = msek;
47         clock_gettime(CLOCK_MONOTONIC, &nextActivation);
48 //      eDebug("this = %p\nnow sec = %d, nsec = %d\nadd %d msec", this, nextActivation.tv_sec, nextActivation.tv_nsec, msek);
49         nextActivation += (msek<0 ? 0 : msek);
50 //      eDebug("next Activation sec = %d, nsec = %d", nextActivation.tv_sec, nextActivation.tv_nsec );
51         context.addTimer(this);
52 }
53
54 void eTimer::startLongTimer( int seconds )
55 {
56         if (bActive)
57                 stop();
58
59         bActive = bSingleShot = true;
60         interval = 0;
61         clock_gettime(CLOCK_MONOTONIC, &nextActivation);
62 //      eDebug("this = %p\nnow sec = %d, nsec = %d\nadd %d sec", this, nextActivation.tv_sec, nextActivation.tv_nsec, seconds);
63         if ( seconds > 0 )
64                 nextActivation.tv_sec += seconds;
65 //      eDebug("next Activation sec = %d, nsec = %d", nextActivation.tv_sec, nextActivation.tv_nsec );
66         context.addTimer(this);
67 }
68
69 void eTimer::stop()
70 {
71         if (bActive)
72         {
73                 bActive=false;
74                 context.removeTimer(this);
75         }
76 }
77
78 void eTimer::changeInterval(long msek)
79 {
80         if (bActive)  // Timer is running?
81         {
82                 context.removeTimer(this);       // then stop
83                 nextActivation -= interval;  // sub old interval
84         }
85         else
86                 bActive=true; // then activate Timer
87
88         interval = msek;                                                // set new Interval
89         nextActivation += interval;             // calc nextActivation
90
91         context.addTimer(this);                         // add Timer to context TimerList
92 }
93
94 void eTimer::activate()   // Internal Funktion... called from eApplication
95 {
96         context.removeTimer(this);
97
98         if (!bSingleShot)
99         {
100                 nextActivation += interval;
101                 context.addTimer(this);
102         }
103         else
104                 bActive=false;
105
106         /*emit*/ timeout();
107 }
108
109 // mainloop
110 ePtrList<eMainloop> eMainloop::existing_loops;
111
112 eMainloop::~eMainloop()
113 {
114         existing_loops.remove(this);
115         for (std::map<int, eSocketNotifier*>::iterator it(notifiers.begin());it != notifiers.end();++it)
116                 it->second->stop();
117         while(m_timer_list.begin() != m_timer_list.end())
118                 m_timer_list.begin()->stop();
119 }
120
121 void eMainloop::addSocketNotifier(eSocketNotifier *sn)
122 {
123         int fd = sn->getFD();
124         ASSERT(notifiers.find(fd) == notifiers.end());
125         notifiers[fd]=sn;
126 }
127
128 void eMainloop::removeSocketNotifier(eSocketNotifier *sn)
129 {
130         int fd = sn->getFD();
131         std::map<int,eSocketNotifier*>::iterator i(notifiers.find(fd));
132         if (i != notifiers.end())
133                 return notifiers.erase(i);
134         eFatal("removed socket notifier which is not present");
135 }
136
137 int eMainloop::processOneEvent(unsigned int twisted_timeout, PyObject **res, ePyObject additional)
138 {
139         int return_reason = 0;
140                 /* get current time */
141
142         if (additional && !PyDict_Check(additional))
143                 eFatal("additional, but it's not dict");
144
145         if (additional && !res)
146                 eFatal("additional, but no res");
147
148         long poll_timeout = -1; /* infinite in case of empty timer list */
149
150         if (!m_timer_list.empty() || twisted_timeout > 0)
151         {
152                 if (!m_timer_list.empty())
153                 {
154                         /* process all timers which are ready. first remove them out of the list. */
155                         while (!m_timer_list.empty() && (poll_timeout = timeout_usec( m_timer_list.begin()->getNextActivation() ) ) <= 0 )
156                                 m_timer_list.begin()->activate();
157                         if (poll_timeout < 0)
158                                 poll_timeout = 0;
159                         else /* convert us to ms */
160                                 poll_timeout /= 1000;
161                 }
162         }
163
164         if ((twisted_timeout > 0) && (poll_timeout > 0) && ((unsigned int)poll_timeout > twisted_timeout))
165         {
166                 poll_timeout = twisted_timeout;
167                 return_reason = 1;
168         }
169
170         int nativecount=notifiers.size(),
171                 fdcount=nativecount,
172                 ret=0;
173
174         if (additional)
175                 fdcount += PyDict_Size(additional);
176
177                 // build the poll aray
178         pollfd pfd[fdcount];  // make new pollfd array
179         std::map<int,eSocketNotifier*>::iterator it = notifiers.begin();
180         int i=0;
181         for (; i < nativecount; ++i, ++it)
182         {
183                 it->second->state = 1; // running and in poll
184                 pfd[i].fd = it->first;
185                 pfd[i].events = it->second->getRequested();
186         }
187
188         if (additional)
189         {
190                 PyObject *key, *val;
191                 Py_ssize_t pos=0;
192                 while (PyDict_Next(additional, &pos, &key, &val)) {
193                         pfd[i].fd = PyObject_AsFileDescriptor(key);
194                         pfd[i++].events = PyInt_AsLong(val);
195                 }
196         }
197
198         m_is_idle = 1;
199
200         if (this == eApp)
201         {
202                 Py_BEGIN_ALLOW_THREADS
203                 ret = ::poll(pfd, fdcount, poll_timeout);
204                 Py_END_ALLOW_THREADS
205         } else
206                 ret = ::poll(pfd, fdcount, poll_timeout);
207
208         m_is_idle = 0;
209
210                         /* ret > 0 means that there are some active poll entries. */
211         if (ret > 0)
212         {
213                 int i=0;
214                 return_reason = 0;
215                 for (; i < nativecount; ++i)
216                 {
217                         if (pfd[i].revents)
218                         {
219                                 it = notifiers.find(pfd[i].fd);
220                                 if (it != notifiers.end()
221                                         && it->second->state == 1) // added and in poll
222                                 {
223                                         int req = it->second->getRequested();
224                                         if (pfd[i].revents & req)
225                                                 it->second->activate(pfd[i].revents & req);
226                                         pfd[i].revents &= ~req;
227                                 }
228                                 if (pfd[i].revents & (POLLERR|POLLHUP|POLLNVAL))
229                                         eDebug("poll: unhandled POLLERR/HUP/NVAL for fd %d(%d)", pfd[i].fd, pfd[i].revents);
230                         }
231                 }
232                 for (; i < fdcount; ++i)
233                 {
234                         if (pfd[i].revents)
235                         {
236                                 if (!*res)
237                                         *res = PyList_New(0);
238                                 ePyObject it = PyTuple_New(2);
239                                 PyTuple_SET_ITEM(it, 0, PyInt_FromLong(pfd[i].fd));
240                                 PyTuple_SET_ITEM(it, 1, PyInt_FromLong(pfd[i].revents));
241                                 PyList_Append(*res, it);
242                                 Py_DECREF(it);
243                         }
244                 }
245         }
246         else if (ret < 0)
247         {
248                         /* when we got a signal, we get EINTR. */
249                 if (errno != EINTR)
250                         eDebug("poll made error (%m)");
251                 else
252                         return_reason = 2; /* don't assume the timeout has passed when we got a signal */
253         }
254
255         return return_reason;
256 }
257
258 void eMainloop::addTimer(eTimer* e)
259 {
260         m_timer_list.insert_in_order(e);
261 }
262
263 void eMainloop::removeTimer(eTimer* e)
264 {
265         m_timer_list.remove(e);
266 }
267
268 int eMainloop::iterate(unsigned int twisted_timeout, PyObject **res, ePyObject dict)
269 {
270         int ret = 0;
271
272         if (twisted_timeout)
273         {
274                 clock_gettime(CLOCK_MONOTONIC, &m_twisted_timer);
275                 m_twisted_timer += twisted_timeout;
276         }
277
278                 /* TODO: this code just became ugly. fix that. */
279         do
280         {
281                 if (m_interrupt_requested)
282                 {
283                         m_interrupt_requested = 0;
284                         return 0;
285                 }
286
287                 if (app_quit_now)
288                         return -1;
289
290                 int to = 0;
291                 if (twisted_timeout)
292                 {
293                         timespec now, timeout;
294                         clock_gettime(CLOCK_MONOTONIC, &now);
295                         if (m_twisted_timer<=now) // timeout
296                                 return 0;
297                         timeout = m_twisted_timer - now;
298                         to = timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000;
299                 }
300                 ret = processOneEvent(to, res, dict);
301         } while ( !ret && !(res && *res) );
302
303         return ret;
304 }
305
306 int eMainloop::runLoop()
307 {
308         while (!app_quit_now)
309                 iterate();
310         return retval;
311 }
312
313 void eMainloop::reset()
314 {
315         app_quit_now=false;
316 }
317
318 PyObject *eMainloop::poll(ePyObject timeout, ePyObject dict)
319 {
320         PyObject *res=0;
321
322         if (app_quit_now)
323                 Py_RETURN_NONE;
324
325         int twisted_timeout = (timeout == Py_None) ? 0 : PyInt_AsLong(timeout);
326
327         iterate(twisted_timeout, &res, dict);
328         if (res)
329                 return res;
330
331         return PyList_New(0); /* return empty list on timeout */
332 }
333
334 void eMainloop::interruptPoll()
335 {
336         m_interrupt_requested = 1;
337 }
338
339 void eMainloop::quit(int ret)
340 {
341         retval = ret;
342         app_quit_now = true;
343 }
344
345 eApplication* eApp = 0;
346
347 #include "structmember.h"
348
349 extern "C" {
350
351 // eTimer replacement
352
353 struct eTimerPy
354 {
355         PyObject_HEAD
356         eTimer *tm;
357         PyObject *in_weakreflist; /* List of weak references */
358 };
359
360 static int
361 eTimerPy_traverse(eTimerPy *self, visitproc visit, void *arg)
362 {
363         PyObject *obj = self->tm->timeout.get();
364         Py_VISIT(obj);
365         return 0;
366 }
367
368 static int
369 eTimerPy_clear(eTimerPy *self)
370 {
371         PyObject *obj = self->tm->timeout.get();
372         Py_CLEAR(obj);
373         return 0;
374 }
375
376 static void
377 eTimerPy_dealloc(eTimerPy* self)
378 {
379         if (self->in_weakreflist != NULL)
380                 PyObject_ClearWeakRefs((PyObject *) self);
381         eTimerPy_clear(self);
382         delete self->tm;
383         self->ob_type->tp_free((PyObject*)self);
384 }
385
386 static PyObject *
387 eTimerPy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
388 {
389         eTimerPy *self = (eTimerPy *)type->tp_alloc(type, 0);
390         self->tm = new eTimer(eApp);
391         self->in_weakreflist = NULL;
392         return (PyObject *)self;
393 }
394
395 static PyObject *
396 eTimerPy_is_active(eTimerPy* self)
397 {
398         PyObject *ret = NULL;
399         ret = self->tm->isActive() ? Py_True : Py_False;
400         Org_Py_INCREF(ret);
401         return ret;
402 }
403
404 static PyObject *
405 eTimerPy_start(eTimerPy* self, PyObject *args)
406 {
407         long v=0;
408         long singleShot=0;
409         if (PyTuple_Size(args) > 1)
410         {
411                 if (!PyArg_ParseTuple(args, "ll", &v, &singleShot)) // when 2nd arg is a value
412                 {
413                         PyObject *obj=0;
414                         if (!PyArg_ParseTuple(args, "lO", &v, &obj)) // get 2nd arg as python object
415                                 return NULL;
416                         else if (obj == Py_True)
417                                 singleShot=1;
418                         else if (obj != Py_False)
419                                 return NULL;
420                 }
421         }
422         else if (!PyArg_ParseTuple(args, "l", &v))
423                 return NULL;
424         self->tm->start(v, singleShot);
425         Py_RETURN_NONE;
426 }
427
428 static PyObject *
429 eTimerPy_start_long(eTimerPy* self, PyObject *args)
430 {
431         long v=0;
432         if (!PyArg_ParseTuple(args, "l", &v)) {
433                 return NULL;
434         }
435         self->tm->startLongTimer(v);
436         Py_RETURN_NONE;
437 }
438
439 static PyObject *
440 eTimerPy_change_interval(eTimerPy* self, PyObject *args)
441 {
442         long v=0;
443         if (!PyArg_ParseTuple(args, "l", &v)) {
444                 return NULL;
445         }
446         self->tm->changeInterval(v);
447         Py_RETURN_NONE;
448 }
449
450 static PyObject *
451 eTimerPy_stop(eTimerPy* self)
452 {
453         self->tm->stop();
454         Py_RETURN_NONE;
455 }
456
457 static PyObject *
458 eTimerPy_get_callback_list(eTimerPy *self)
459 { //used for compatibilty with the old eTimer
460         return self->tm->timeout.get();
461 }
462
463 static PyMethodDef eTimerPy_methods[] = {
464         {"isActive", (PyCFunction)eTimerPy_is_active, METH_NOARGS,
465          "returns the timer state"
466         },
467         {"start", (PyCFunction)eTimerPy_start, METH_VARARGS,
468          "start timer with interval in msecs"
469         },
470         {"startLongTimer", (PyCFunction)eTimerPy_start_long, METH_VARARGS,
471          "start timer with interval in secs"
472         },
473         {"changeInterval", (PyCFunction)eTimerPy_change_interval, METH_VARARGS,
474          "change interval of a timer (in msecs)"
475         },
476         {"stop", (PyCFunction)eTimerPy_stop, METH_NOARGS,
477          "stops the timer"
478         },
479         //used for compatibilty with the old eTimer
480         {"get", (PyCFunction)eTimerPy_get_callback_list, METH_NOARGS,
481          "get timeout callback list"
482         },
483         {NULL}  /* Sentinel */
484 };
485
486 static PyObject *
487 eTimerPy_get_cb_list(eTimerPy *self, void *closure)
488 {
489         return self->tm->timeout.get();
490 }
491
492 static PyObject *
493 eTimerPy_timeout(eTimerPy *self, void *closure) 
494 { //used for compatibilty with the old eTimer
495         Org_Py_INCREF((PyObject*)self);
496         return (PyObject*)self;
497 }
498
499 static PyGetSetDef eTimerPy_getseters[] = {
500         {"callback",
501          (getter)eTimerPy_get_cb_list, (setter)0,
502          "returns the callback python list",
503          NULL},
504
505         {"timeout", //used for compatibilty with the old eTimer
506          (getter)eTimerPy_timeout, (setter)0,
507          "synonym for our self",
508          NULL},
509
510         {NULL} /* Sentinel */
511 };
512
513 static PyTypeObject eTimerPyType = {
514         PyObject_HEAD_INIT(NULL)
515         0, /*ob_size*/
516         "eBaseImpl.eTimer", /*tp_name*/
517         sizeof(eTimerPy), /*tp_basicsize*/
518         0, /*tp_itemsize*/
519         (destructor)eTimerPy_dealloc, /*tp_dealloc*/
520         0, /*tp_print*/
521         0, /*tp_getattr*/
522         0, /*tp_setattr*/
523         0, /*tp_compare*/
524         0, /*tp_repr*/
525         0, /*tp_as_number*/
526         0, /*tp_as_sequence*/
527         0, /*tp_as_mapping*/
528         0, /*tp_hash */
529         0, /*tp_call*/
530         0, /*tp_str*/
531         0, /*tp_getattro*/
532         0, /*tp_setattro*/
533         0, /*tp_as_buffer*/
534         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
535         "eTimer objects", /* tp_doc */
536         (traverseproc)eTimerPy_traverse, /* tp_traverse */
537         (inquiry)eTimerPy_clear, /* tp_clear */
538         0, /* tp_richcompare */
539         offsetof(eTimerPy, in_weakreflist), /* tp_weaklistoffset */
540         0, /* tp_iter */
541         0, /* tp_iternext */
542         eTimerPy_methods, /* tp_methods */
543         0, /* tp_members */
544         eTimerPy_getseters, /* tp_getset */
545         0, /* tp_base */
546         0, /* tp_dict */
547         0, /* tp_descr_get */
548         0, /* tp_descr_set */
549         0, /* tp_dictoffset */
550         0, /* tp_init */
551         0, /* tp_alloc */
552         eTimerPy_new, /* tp_new */
553 };
554
555 // eSocketNotifier replacement
556
557 struct eSocketNotifierPy
558 {
559         PyObject_HEAD
560         eSocketNotifier *sn;
561         PyObject *in_weakreflist; /* List of weak references */
562 };
563
564 static int
565 eSocketNotifierPy_traverse(eSocketNotifierPy *self, visitproc visit, void *arg)
566 {
567         PyObject *obj = self->sn->activated.get();
568         Py_VISIT(obj);
569         return 0;
570 }
571
572 static int
573 eSocketNotifierPy_clear(eSocketNotifierPy *self)
574 {
575         PyObject *obj = self->sn->activated.get();
576         Py_CLEAR(obj);
577         return 0;
578 }
579
580 static void
581 eSocketNotifierPy_dealloc(eSocketNotifierPy* self)
582 {
583         if (self->in_weakreflist != NULL)
584                 PyObject_ClearWeakRefs((PyObject *) self);
585         eSocketNotifierPy_clear(self);
586         delete self->sn;
587         self->ob_type->tp_free((PyObject*)self);
588 }
589
590 static PyObject *
591 eSocketNotifierPy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
592 {
593         eSocketNotifierPy *self = (eSocketNotifierPy *)type->tp_alloc(type, 0);
594         int fd, req, immediate_start = 1, size = PyTuple_Size(args);
595         if (size > 2)
596         {
597                 if (!PyArg_ParseTuple(args, "iii", &fd, &req, &immediate_start))
598                 {
599                         PyObject *obj = NULL;
600                         if (!PyArg_ParseTuple(args, "iiO", &fd, &req, &immediate_start))
601                                 return NULL;
602                         if (obj == Py_False)
603                                 immediate_start = 0;
604                         else if (obj != Py_True)
605                                 return NULL;
606                 }
607         }
608         else if (size < 2 || !PyArg_ParseTuple(args, "ii", &fd, &req))
609                 return NULL;
610         self->sn = new eSocketNotifier(eApp, fd, req, immediate_start);
611         self->in_weakreflist = NULL;
612         return (PyObject *)self;
613 }
614
615 static PyObject *
616 eSocketNotifierPy_is_running(eSocketNotifierPy* self)
617 {
618         PyObject *ret = self->sn->isRunning() ? Py_True : Py_False;
619         Org_Py_INCREF(ret);
620         return ret;
621 }
622
623 static PyObject *
624 eSocketNotifierPy_start(eSocketNotifierPy* self)
625 {
626         self->sn->start();
627         Py_RETURN_NONE;
628 }
629
630 static PyObject *
631 eSocketNotifierPy_stop(eSocketNotifierPy* self)
632 {
633         self->sn->stop();
634         Py_RETURN_NONE;
635 }
636
637 static PyObject *
638 eSocketNotifierPy_get_fd(eSocketNotifierPy* self)
639 {
640         return PyInt_FromLong(self->sn->getFD());
641 }
642
643 static PyObject *
644 eSocketNotifierPy_get_requested(eSocketNotifierPy* self)
645 {
646         return PyInt_FromLong(self->sn->getRequested());
647 }
648
649 static PyObject *
650 eSocketNotifierPy_set_requested(eSocketNotifierPy* self, PyObject *args)
651 {
652         int req;
653         if (PyTuple_Size(args) != 1 || !PyArg_ParseTuple(args, "i", &req))
654                 return NULL;
655         self->sn->setRequested(req);
656         Py_RETURN_NONE;
657 }
658
659 static PyMethodDef eSocketNotifierPy_methods[] = {
660         {"isRunning", (PyCFunction)eSocketNotifierPy_is_running, METH_NOARGS,
661          "returns the running state"
662         },
663         {"start", (PyCFunction)eSocketNotifierPy_start, METH_NOARGS,
664          "start the sn"
665         },
666         {"stop", (PyCFunction)eSocketNotifierPy_stop, METH_NOARGS,
667          "stops the sn"
668         },
669         {"getFD", (PyCFunction)eSocketNotifierPy_get_fd, METH_NOARGS,
670          "get file descriptor"
671         },
672         {"getRequested", (PyCFunction)eSocketNotifierPy_get_requested, METH_NOARGS,
673          "get requested"
674         },
675         {"setRequested", (PyCFunction)eSocketNotifierPy_set_requested, METH_VARARGS,
676          "set requested"
677         },
678         {NULL}  /* Sentinel */
679 };
680
681 static PyObject *
682 eSocketNotifierPy_get_cb_list(eSocketNotifierPy *self, void *closure)
683 {
684         return self->sn->activated.get();
685 }
686
687 static PyGetSetDef eSocketNotifierPy_getseters[] = {
688         {"callback",
689          (getter)eSocketNotifierPy_get_cb_list, (setter)0,
690          "returns the callback python list",
691          NULL},
692         {NULL} /* Sentinel */
693 };
694
695 static PyTypeObject eSocketNotifierPyType = {
696         PyObject_HEAD_INIT(NULL)
697         0, /*ob_size*/
698         "eBaseImpl.eSocketNotifier", /*tp_name*/
699         sizeof(eSocketNotifierPy), /*tp_basicsize*/
700         0, /*tp_itemsize*/
701         (destructor)eSocketNotifierPy_dealloc, /*tp_dealloc*/
702         0, /*tp_print*/
703         0, /*tp_getattr*/
704         0, /*tp_setattr*/
705         0, /*tp_compare*/
706         0, /*tp_repr*/
707         0, /*tp_as_number*/
708         0, /*tp_as_sequence*/
709         0, /*tp_as_mapping*/
710         0, /*tp_hash */
711         0, /*tp_call*/
712         0, /*tp_str*/
713         0, /*tp_getattro*/
714         0, /*tp_setattro*/
715         0, /*tp_as_buffer*/
716         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
717         "eTimer objects", /* tp_doc */
718         (traverseproc)eSocketNotifierPy_traverse, /* tp_traverse */
719         (inquiry)eSocketNotifierPy_clear, /* tp_clear */
720         0, /* tp_richcompare */
721         offsetof(eSocketNotifierPy, in_weakreflist), /* tp_weaklistoffset */
722         0, /* tp_iter */
723         0, /* tp_iternext */
724         eSocketNotifierPy_methods, /* tp_methods */
725         0, /* tp_members */
726         eSocketNotifierPy_getseters, /* tp_getset */
727         0, /* tp_base */
728         0, /* tp_dict */
729         0, /* tp_descr_get */
730         0, /* tp_descr_set */
731         0, /* tp_dictoffset */
732         0, /* tp_init */
733         0, /* tp_alloc */
734         eSocketNotifierPy_new, /* tp_new */
735 };
736
737 static PyMethodDef module_methods[] = {
738         {NULL}  /* Sentinel */
739 };
740
741 void eBaseInit(void)
742 {
743         PyObject* m;
744
745         m = Py_InitModule3("eBaseImpl", module_methods,
746                 "Module that implements some enigma classes with working cyclic garbage collection.");
747
748         if (m == NULL)
749                 return;
750
751         if (!PyType_Ready(&eTimerPyType))
752         {
753                 Org_Py_INCREF((PyObject*)&eTimerPyType);
754                 PyModule_AddObject(m, "eTimer", (PyObject*)&eTimerPyType);
755         }
756         if (!PyType_Ready(&eSocketNotifierPyType))
757         {
758                 Org_Py_INCREF((PyObject*)&eSocketNotifierPyType);
759                 PyModule_AddObject(m, "eSocketNotifier", (PyObject*)&eSocketNotifierPyType);
760         }
761 }
762 }