1 static char rcsid[] = "$Id: sunsigio.c,v 1.1 1996/07/09 19:42:47 paul Exp $";
2
3 /*
4 * This file contains support for handling SunOS SIGIO signals. A SIGIO
5 * signal is sent whenever input is available on a descriptor that has had
6 * SIGIO delivery enabled for it (this enabling is not carried out by these
7 * functions). There are two entry points:
8 * - sunio_install_handler - Called to record an association between
9 * a SunOS descriptor and a handler in the
10 * smx handler.
11 * - sunio_interrupt - a SIGIO has occurred. Check all descriptors
12 * registered with us, and call handler that input
13 * is available for.
14 */
15
16 #include "kernel.h"
17 #include <sun/syscall.h>
18
19 #define NUM_CALLBACKS 10
20
21 /*
22 * Call back functions registered with us.
23 */
24 typedef struct callback {
25 void (*handler)(int fd);
26 } callback_t;
27
28 callback_t callbacks[NUM_CALLBACKS];
29 static int num_cbs = 0;
30
31 /*
32 * POLLIN and the pollfd struct must agree with /usr/include/sys/poll.h
33 * We supply fds to polls(2) to see which descriptors have input available
34 * on them.
35 */
36 #define POLLIN 0x1
37
38 static struct pollfd {
39 int fd; /* file descriptor */
40 short events; /* requested events */
41 short revents; /* returned events */
42 } fds[NUM_CALLBACKS];
43
44
45 /*
46 * Local functions
47 */
48 static void check_for_input(void);
49 static int check_desc(int cb);
50
51
52 /*
53 * Function: sunio_install_handler
54 * Parameters: fd - descriptor to install handler for
55 * handler - SIGIO handler for fd
56 *
57 * Record the fd/handler association, and include fd in the array supplied
58 * to poll.
59 */
60 void sunio_install_handler(int fd, void (*handler)(int fd))
61 {
62 if (num_cbs == NUM_CALLBACKS) {
63 panic("sunio_install_handler: number of callbacks exceeds array size",
64 NO_NUM);
65 }
66 callbacks[num_cbs].handler = handler;
67 fds[num_cbs].fd = fd;
68 fds[num_cbs].events = POLLIN;
69 num_cbs++;
70 }
71
72
73 /*
74 * Function: sunio_interrupt
75 *
76 * The function is called upon receiving a SunOS SIGIO signal. It checks
77 * all registered fd's for input, and calls handlers for those fd's that
78 * have input available.
79 */
80 void sunio_interrupt(void)
81 {
82 int poll;
83
84 /*
85 * Poll all descriptors for input. Because this is only executed by
86 * layer 1 code, a lock is implicitly in force.
87 */
88 check_for_input();
89 for (poll = 0; poll < num_cbs; poll++) {
90 if (check_desc(poll)) {
91 (*callbacks[poll].handler)(fds[poll].fd);
92 }
93 }
94 }
95
96
97 /*
98 * Function: check_for_input
99 *
100 * This function calls poll to initialise the revent fields of fds in
101 * preparation for subsequent calls to check_desc.
102 */
103 static void check_for_input(void)
104 {
105 int i;
106
107 for (i = 0; i < num_cbs; i++) {
108 fds[i].revents = 0;
109 }
110
111 if (SunOS(SYS_poll, &fds, num_cbs, 0) == -1) {
112 panic("poll failed", NO_NUM);
113 }
114 }
115
116
117 /*
118 * Function: check_desc
119 * Parameter: cb - index into callback info
120 * Returns: true if input is available for callback cb, false otherwise
121 */
122 static int check_desc(int cb)
123 {
124 return (fds[cb].revents & POLLIN) == POLLIN;
125 }
126
127
128
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.