1 /* $XConsortium: iopreader.c,v 1.2 94/04/12 17:24:33 dpw Exp $ */
3 /* Copyright (c) 1987 by the Regents of the University of California
4 * Copyright (c) 1994 by the Vrije Universiteit, Amsterdam.
6 * Permission to use, copy, modify, and distribute this
7 * software and its documentation for any purpose and without
8 * fee is hereby granted, provided that the above copyright
9 * notice appear in all copies. The University of California
10 * and the Vrije Universiteit make no representations about
11 * the suitability of this software for any purpose.
12 * It is provided "as is" without express or implied warranty.
20 #define port am_port_t
26 #include <server/iop/iop.h>
31 #define DEVREADER_STACK 8000
32 #define MAXEVENTQUEUE 32
37 static semaphore empty, filled;
39 static IOPEvent event_queue[MAXEVENTQUEUE];
40 static int event_qin, event_qout;
43 static void IOPServerReader();
46 * Initialize the IOP server
49 InitializeIOPServerReader()
55 * Initialize event queue
57 event_qin = event_qout = 0;
58 sema_init(&empty, MAXEVENTQUEUE);
59 sema_init(&filled, 0);
63 * Get IOP capability, and enable the server
65 if (XServerHostName == NULL)
66 FatalError("No hostname, no screen\n");
68 if ((err = host_lookup(XServerHostName, &hostcap)) != STD_OK ||
69 (err = dir_lookup(&hostcap, DEF_IOPSVRNAME, &iopcap)) != STD_OK)
71 FatalError("Cannot find IOP server for %s: %s\n",
72 XServerHostName, err_why(err));
78 if ((err = iop_enable(&iopcap)) != STD_OK)
79 FatalError("iop_enable failed (%s)\n", err_why(err));
82 * Start IOP reader thread
85 if (thread_newthread(IOPServerReader, DEVREADER_STACK, 0, 0) <= 0)
86 FatalError("Cannot start IOP reader thread\n");
90 * IOP clean up, actuall disable the IOP server. Its the IOP's own choice
91 * what do do (perhaps restore the screen?).
98 if ((err = iop_disable(&iopcap)) != STD_OK)
99 ErrorF("iop_disable failed (%s)\n", err_why(err));
103 * This threads polls the IOP server for events. Once an event (or a
104 * number of events) are read, they are queued up using a traditional
105 * producer/consumer approach.
110 IOPEvent queue[MAXEVENTQUEUE-1];
114 WaitForInitialization();
117 if (amDebug) ErrorF("IOPServerReader() running ...\n");
122 nevents = MAXEVENTQUEUE - 1;
123 err = iop_getevents(&iopcap, queue, &nevents);
125 if (err != RPC_FAILURE) {
126 ErrorF("iop_getevents failed (%s)\n", err_why(err));
130 } while (nevents <= 0);
132 /* store event(s) in the global event queue */
133 sema_mdown(&empty, nevents);
135 for (i = 0; i < nevents; i++) {
136 event_queue[event_qin] = queue[i];
137 event_qin = (event_qin + 1) % MAXEVENTQUEUE;
140 sema_mup(&filled, nevents);
146 * Return the number of IOP events waiting
149 AmoebaEventsAvailable()
151 return sema_level(&filled);
155 * Get the IOP events from the queue. ``size'' is the maximum the
156 * requestor cares to handle, the actual size read is returned as
160 AmoebaGetEvents(queue, size)
166 if (sema_level(&filled) <= 0) return 0;
167 if ((nevents = sema_level(&filled)) > size)
169 sema_mdown(&filled, nevents);
171 for (i = 0; i < nevents; i++) {
172 queue[i] = event_queue[event_qout];
173 event_qout = (event_qout + 1) % MAXEVENTQUEUE;
176 sema_mup(&empty, nevents);