Source code for virtualbox.events

"""Manage VBoxEvent, registration, listening and processing

By Michael Dorman
[mjdorma+pyvbox@gmail.com]
"""
from __future__ import print_function
import sys
import atexit
import inspect
import traceback
import threading

from virtualbox import library


_lookup = {}


def type_to_interface(event_type):
    """Return the event interface object that corresponds to the event type
    enumeration"""
    global _lookup
    if not isinstance(event_type, library.VBoxEventType):
        raise TypeError("event_type was not of VBoxEventType")
    if not _lookup:
        for attr in dir(library):
            event_interface = getattr(library, attr)
            if not inspect.isclass(event_interface):
                continue
            if not issubclass(event_interface, library.Interface):
                continue
            et = getattr(event_interface, 'id', None)
            if et is None:
                continue
            if not isinstance(et, library.VBoxEventType):
                continue
            _lookup[int(et)] = event_interface
    return _lookup[int(event_type)]


_callbacks = {}


def _event_monitor(callback, event_source, listener, event_interface, quit):
    global _callbacks
    try:
        while not quit.is_set():
            try:
                event = event_source.get_event(listener, 1000)
            except library.VBoxError:
                print("Unregistering %s due to VBoxError on get_event" %
                      listener, file=sys.stderr)
                break
            if event:
                try:
                    callback(event_interface(event))
                except:
                    print("Unhanded exception in callback: \n%s" %
                          traceback.format_exc(), file=sys.stderr)
                event_source.event_processed(listener, event)
    finally:
        _callbacks.pop(threading.current_thread().ident, None)
        try:
            event_source.unregister_listener(listener)
        except Exception:
            print("Failed to unregister listener %s" % listener,
                  file=sys.stderr)


[docs]def register_callback(callback, event_source, event_type): """register a callback function against an event_source for a given event_type. Arguments: callback - function to call when the event occurs event_source - the source to monitor events in event_type - the type of event we're monitoring for returns the registration id (callback_id) """ global _callbacks event_interface = type_to_interface(event_type) listener = event_source.create_listener() event_source.register_listener(listener, [event_type], False) quit = threading.Event() t = threading.Thread(target=_event_monitor, args=(callback, event_source, listener, event_interface, quit)) t.daemon = True t.start() while t.is_alive() is False: continue _callbacks[t.ident] = (t, quit) return t.ident
[docs]def unregister_callback(callback_id): """unregister a callback registration""" global _callbacks obj = _callbacks.pop(callback_id, None) threads = [] if obj is not None: t, quit = obj quit.set() threads.append(t) for t in threads: t.join()
def _remove_all_callbacks(): global _callbacks for callback_id in list(_callbacks): unregister_callback(callback_id) atexit.register(_remove_all_callbacks)