# emacs-mode: -*- python-*-
import time
from pdis.lib.best_threading import start_thread
from pdis.lib.logging import *
from pdis.lib.priority import set_thread_priority
from aosocket.abst_async_mgr import AbstAsyncMgr
from aosocket.async_socket_exceptions import *
from aosocket.settings import logging_enabled
from aosocket.symbian.symbian_itc import SymbianItc
from aosocket.symbian.symbian_socket import SymbianSocketServ
from aosocketnativenew import AoImmediate, AoLoop
class SymbianAsyncMgr(AbstAsyncMgr,):
    __module__ = __name__
    __doc__ = '\n    This class implements a base class for socket managers that use\n    sockets in an asynchronous manner in a Symbian environment.\n\n    Each instance of this class has an internal thread that makes any\n    asynchronous requests on the sockets managed by the instance,\n    allowing many requests on many sockets to be outstanding at any\n    one time. The thread is driven by its own native active scheduler,\n    i.e. the thread does nothing but responds to events issued by the\n    active scheduler.\n    '

    def __init__(self, thread_pri = None):
        AbstAsyncMgr.__init__(self)
        if thread_pri:
            self.thread_pri = thread_pri
        else:
            self.thread_pri = 500



    def create_internal_thread(self):
        '\n        This method creates and starts the internal thread that owns\n        all the sockets, storing a reference to it in the internal\n        ``thread`` property.\n        '
        self.itc = SymbianItc()
        if logging_enabled():
            logwrite('starting internal thread')
        self.thread = None
        self.thread = start_thread(target=self._SymbianAsyncMgr__loop, name=('socket-owner-thread-%d' % hash(self)), args=())



    def __loop(self):
        '\n        The thread that owns all the sockets runs this loop that\n        processes all asynchronous events, as well as decides how to\n        handle any requests in the internal queue. To get this thread\n        to do something for you (instead of blocking and waiting for\n        events), simply queue a new asynchronous request for the\n        thread to deal with.\n        '
        try:
            if logging_enabled():
                logwrite('internal thread running')
                logwrite('logging enabled')
            while (not self.thread):
                time.sleep(0.10000000000000001)

            set_thread_priority(self.thread_pri)
            self.aoloop = AoLoop()
            self.aoloop.open()
            self.immediate = AoImmediate()
            self.immediate.open()
            self.itc.open()
            if logging_enabled():
                logwrite('creating socket server handle')
            self.socket_serv = SymbianSocketServ()
            self.immediate.complete(self._SymbianAsyncMgr__req_init, None)
            if logging_enabled():
                logwrite('starting ao loop')
            self.aoloop.start()
            if logging_enabled():
                logwrite('ao loop exited')
            self._SymbianAsyncMgr__process_any_requests()
            self.cancel_all_pending_requests()
            self.close_all_managed_sockets()
            self.socket_serv.close()
            self.aoloop.close()
            self.immediate.close()
            self.itc.close()
            if logging_enabled():
                logwrite('stopping logging for internal thread')
            thread_finish_logging()
            self.dead = True
        except:
            log_exception()



    def __req_init(self, error, dummy_param):
        '\n        Starts accepting requests. No requests, not even a ``close``\n        request can be delivered to the internal thread before this\n        has been done.\n        '
        try:
            self.mutex.acquire()
            try:
                self.itc.request(self._SymbianAsyncMgr__got_request, None)
                self.condition.signal()

            finally:
                self.mutex.release()

        except:
            log_exception()



    def __process_any_requests(self):
        self.mutex.acquire()
        try:
            reqs = self.drain()

        finally:
            self.mutex.release()

        for req in reqs:
            self.process_request(req)




    def __got_request(self, error, dummy_param):
        try:
            assert (error == 0)
            self._SymbianAsyncMgr__process_any_requests()
            self.mutex.acquire()
            try:
                if self.dying:
                    self.may_signal = False
                    self.condition.signal_all()
                    self.aoloop.stop()
                else:
                    self.itc.request(self._SymbianAsyncMgr__got_request, None)
                    self.condition.signal()

            finally:
                self.mutex.release()

        except:
            log_exception()




# local variables:
# tab-width: 4
