1
0
mirror of https://github.com/JoelBender/bacpypes synced 2025-10-05 22:18:16 +08:00
bacpypes/doc/source/modules/event.rst

110 lines
3.9 KiB
ReStructuredText

.. BACpypes event module
.. module:: event
Event
=====
At the heart of :func:`core.run()` is a call to the **select** function of the
built in select module. That function is provided a list of file descriptors
and will exit when there is activity on one of them.
In a multi-threaded application, if the main thread is waiting for IO activity
then child threads need a mechanism to "wake up" the main thread. This may be
because the child thread has detected some timeout.
An instance of this class is used by the :class:`task.TaskManager` to wake up
the main thread when tasks are scheduled by child threads. If the child thread
is requesting "as soon as possible" execution of the task, then scheduling the
task wakes up the main thread, which causes it to be processed.
.. note::
This is not available on Windows platforms, which may suffer from a small
preformance hit. This can be mitigated somewhat by changing the **SPIN**
value in the **core** module.
Classes
-------
.. class:: WaitableEvent
The methods in this class provide the same interface as
**asyncore.file_dispatcher** and the ones that are typically used
in multi-threaded applications the way **Threading.Event** objects
are used.
These methods use an internal pipe to provide a "read" and "write" file
descriptors. There are no direct references to this pipe, only through
the file descriptors that are linked to it.
.. method:: __init__()
The internal file descriptors which are understood by the
**asyncore.loop** call in :func:`core.run()` are created by
calling **os.pipe()**, then initialization continues to
the usual **asyncore.file_dispatcher** initializer.
.. method:: __del__()
When an instance of this class is deleted, the file references to the
"read" and "write" sides of the pipe are closed. The OS will then
delete the pipe.
.. method:: readable()
This method returns ``True`` so it will always be included in the
list of file-like objects when waiting for IO activity.
.. method:: writable()
This method returns ``False`` becuase there is never any pending
write activity like there would be for a actual file or socket.
.. method:: handle_read()
This method performs no activity. If an instance of this event
is "set" then the only way to clear it is by calling :func:`clear()`
which will read the pending character out of the pipe.
.. method:: handle_write()
This function is never called because :func:`writable()` always
returns ``False``.
.. method:: handle_close()
This method is called when a close is requested, so this in
turn passes it to the **asyncore.file_dispatcher.close** function.
.. method:: wait(timeout=None)
:param float timeout: maximum time to wait for the event to be set
Similar to the way the **asyncore.loop** function will wait for
activity on a file descriptor, **select.select** is used by this
method to wait for some activity on the "read" side of its internal
pipe.
The :func:`set()` function will write to the "write" side of the pipe,
so the "read" side will have activity and the select function will
exit.
This function returns ``True`` if the "event" is "set".
.. method:: isSet()
This method calls :func:`wait()` with a zero timeout which essentially
probes the pipe to see if there is data waiting, which in turn implies
the "event" is "set".
.. method:: set()
Setting the event involves writing a single character to the internal
pipe, but only if there is no data in the pipe.
.. method:: clear()
Clearing the event involves reading the character that was written to
the intrenal pipe, provided one is there. If there is no data in the
pipe then the **os.read** function would stall the thread.