X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=Xserver%2Fprograms%2FXserver%2Fos%2Fiopreader.c;fp=Xserver%2Fprograms%2FXserver%2Fos%2Fiopreader.c;h=092c7a7abc36850a6f0032d7846f297a137afc52;hb=b6e6afccf37f4ad0515ef2a698f714fdf1bf23b3;hp=0000000000000000000000000000000000000000;hpb=e3340a110a3b01756b8e67531395a33b40a17d37;p=rdpsrv diff --git a/Xserver/programs/Xserver/os/iopreader.c b/Xserver/programs/Xserver/os/iopreader.c new file mode 100644 index 0000000..092c7a7 --- /dev/null +++ b/Xserver/programs/Xserver/os/iopreader.c @@ -0,0 +1,179 @@ +/* $XConsortium: iopreader.c,v 1.2 94/04/12 17:24:33 dpw Exp $ */ + +/* Copyright (c) 1987 by the Regents of the University of California + * Copyright (c) 1994 by the Vrije Universiteit, Amsterdam. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies. The University of California + * and the Vrije Universiteit make no representations about + * the suitability of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#ifdef AMOEBA +/* + * iopreader.c + * + */ +#define port am_port_t +#include +#include +#include +#include +#include +#include +#undef port + +#include "osdep.h" + +#define DEVREADER_STACK 8000 +#define MAXEVENTQUEUE 32 + +capability iopcap; + +static mutex lock; +static semaphore empty, filled; + +static IOPEvent event_queue[MAXEVENTQUEUE]; +static int event_qin, event_qout; + +void IOPCleanUp(); +static void IOPServerReader(); + +/* + * Initialize the IOP server + */ +void +InitializeIOPServerReader() +{ + capability hostcap; + errstat err; + + /* + * Initialize event queue + */ + event_qin = event_qout = 0; + sema_init(&empty, MAXEVENTQUEUE); + sema_init(&filled, 0); + mu_init(&lock); + + /* + * Get IOP capability, and enable the server + */ + if (XServerHostName == NULL) + FatalError("No hostname, no screen\n"); + + if ((err = host_lookup(XServerHostName, &hostcap)) != STD_OK || + (err = dir_lookup(&hostcap, DEF_IOPSVRNAME, &iopcap)) != STD_OK) + { + FatalError("Cannot find IOP server for %s: %s\n", + XServerHostName, err_why(err)); + } + + /* + * Enable IOP server + */ + if ((err = iop_enable(&iopcap)) != STD_OK) + FatalError("iop_enable failed (%s)\n", err_why(err)); + + /* + * Start IOP reader thread + */ + atexit(IOPCleanUp); + if (thread_newthread(IOPServerReader, DEVREADER_STACK, 0, 0) <= 0) + FatalError("Cannot start IOP reader thread\n"); +} + +/* + * IOP clean up, actuall disable the IOP server. Its the IOP's own choice + * what do do (perhaps restore the screen?). + */ +void +IOPCleanUp() +{ + errstat err; + + if ((err = iop_disable(&iopcap)) != STD_OK) + ErrorF("iop_disable failed (%s)\n", err_why(err)); +} + +/* + * This threads polls the IOP server for events. Once an event (or a + * number of events) are read, they are queued up using a traditional + * producer/consumer approach. + */ +static void +IOPServerReader() +{ + IOPEvent queue[MAXEVENTQUEUE-1]; + int nevents, i; + errstat err; + + WaitForInitialization(); + +#ifdef XDEBUG + if (amDebug) ErrorF("IOPServerReader() running ...\n"); +#endif + + for (;;) { + do { + nevents = MAXEVENTQUEUE - 1; + err = iop_getevents(&iopcap, queue, &nevents); + if (err != STD_OK) { + if (err != RPC_FAILURE) { + ErrorF("iop_getevents failed (%s)\n", err_why(err)); + } + nevents = 0; + } + } while (nevents <= 0); + + /* store event(s) in the global event queue */ + sema_mdown(&empty, nevents); + mu_lock(&lock); + for (i = 0; i < nevents; i++) { + event_queue[event_qin] = queue[i]; + event_qin = (event_qin + 1) % MAXEVENTQUEUE; + } + mu_unlock(&lock); + sema_mup(&filled, nevents); + WakeUpMainThread(); + } +} + +/* + * Return the number of IOP events waiting + */ +int +AmoebaEventsAvailable() +{ + return sema_level(&filled); +} + +/* + * Get the IOP events from the queue. ``size'' is the maximum the + * requestor cares to handle, the actual size read is returned as + * result. + */ +int +AmoebaGetEvents(queue, size) + IOPEvent *queue; + int size; +{ + int nevents, i; + + if (sema_level(&filled) <= 0) return 0; + if ((nevents = sema_level(&filled)) > size) + nevents = size; + sema_mdown(&filled, nevents); + mu_lock(&lock); + for (i = 0; i < nevents; i++) { + queue[i] = event_queue[event_qout]; + event_qout = (event_qout + 1) % MAXEVENTQUEUE; + } + mu_unlock(&lock); + sema_mup(&empty, nevents); + return nevents; +} +#endif /* AMOEBA */