Left Up Right CORBA

Reagieren auf Ereignisse in CORBA

Problem

Ein Corba-Server soll nebenbei noch eine Datei oder einen Netzwerk-Socket überwachen.
Da aber ein Corbaserver hauptsächlich für die Verarbeitung von CORBA-spezifischen Ereignissen (Methodenaufrufen von Corba-Objekten und dergleichen) zuständig ist (ORB::run()), muß nun eine zusätzliche Ereignisquelle eingebunden werden.

Ein Netzwerksocket steckt auch hinter X-Windows (und ähnlichen graphischen Bedinoberflächen). (Frage: Wie macht das andere Betriebssysteme, insbesondere Ereignisbasierte wie WINDOWS und MAC ?).

prinzipielle Betriebssystem-Lösung

Mit dem Systemcall select(2) kann man mehrere Descriptoren (Socket/Datei/...) überwachen.
Dies macht selbstverständlich auch ein MICO-Server so, wie man sich mit strace(1) überzeugen kann.

Damit müssen wir nur herausfinden, wie man über eine API einen Ereignisbearbeiter bei MICO registrieren können.

MICO-Lösung

In MICO wird eine Klasse Dispatcher definiert. "dispatcher" heißt auf deutsch: Fahrdienstleiter, hier regelt so ein Dingens also die Abarbeitung von Ereignissen, man könnte es in diesem Zusammenhang "Verteiler" nennen). Gewöhnlicherweise arbeitet der MICO-Orb mit der Unterklasse SelectDispatcher, die nun eine bequeme Abstraktion um das select(2) ist.
In der Methode SelectDispatcher::run(CORBA::Boolean infinite) (in transport_impl.h definiert und in orb/dispatch.cc implementiert) wird select(2) aufgerufen und das anstehende Ereignis mit einem vorher registrierten Ereignisbehandler abgearbeitet. (falls infinite==TRUE wird das in einer Endlosschleife getan).

Die Funktion ORB::dispatcher() liefert den aktuellen Verteiler des Orbs, wo man Ereignisbehandler eintragen kann.

Die Zeitereignisse werden in Millisekunden angegeben. Wenn die Uhr abgelaufen ist, wird das Ereignis aus der Liste entfernt.

struct DispatcherCallback {
    typedef Dispatcher::Event Event;
    virtual void callback (Dispatcher *, Event) = 0;
    virtual ~DispatcherCallback ();
};
class Dispatcher {
public:
    enum Event { Timer, Read, Write, Except, All, Remove, Moved };
    virtual void rd_event (DispatcherCallback *, Long fd) = 0;
    virtual void wr_event (DispatcherCallback *, Long fd) = 0;
    virtual void ex_event (DispatcherCallback *, Long fd) = 0;
    virtual void tm_event (DispatcherCallback *, ULong tmout) = 0;
    virtual void remove (DispatcherCallback *, Event) = 0;
    virtual void run (Boolean infinite = TRUE) = 0;
    virtual void move (Dispatcher *) = 0;
    virtual Boolean idle () const = 0;

    virtual ~Dispatcher ();
};

Integration mit graphischen Bedienoberflächen

X und jede daraufaufbauende Bibliothek muß selber Ereignisse des Fenstersystemes abarbeiten. Dazu wird ein Verteiler gebraucht, der gemischt sowohl die CORBA- als auch die Fensterereignisse in geeigneter Folge abarbeitet. Für QT wird innerhalb der CApp ("CORBA-Application") ein QT-Dispatcher. Für X11 pur macht das der X11Dispatcher in mico/x11.h. Im Demo-Verzeichnis finden wir unter dispatcher/ die Beispielprogramme für die Kombination mit graphischen Oberflächen.

Der Fremdverteiler wird mit der Operation ORB::dispatcher(disp) gesetzt.

TAO-Lösung

ACE definiert und implementiert das Reactor-Pattern, was auch dem TAO-ORB zugrunde liegt. Implementierungsspezifisch kann man aus dem ORB-Core den Reactor holen und dort zusätzliche Ereignisquellen einbinden.
Arbeitsgruppe Komponenten/CORBA Informatik- und Netzwerkverein Ravensburg e.V Rudolf Weber