2 * Copyright (c) 2003-2004 MontaVista Software, Inc.
3 * Copyright (c) 2006 Sun Microsystems, Inc.
7 * Author: Steven Dake (sdake@mvista.com)
9 * This software licensed under BSD license, the text of which follows:
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are met:
14 * - Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 * - Redistributions in binary form must reproduce the above copyright notice,
17 * this list of conditions and the following disclaimer in the documentation
18 * and/or other materials provided with the distribution.
19 * - Neither the name of the MontaVista Software, Inc. nor the names of its
20 * contributors may be used to endorse or promote products derived from this
21 * software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
33 * THE POSSIBILITY OF SUCH DAMAGE.
43 #include "../include/list.h"
44 #include "../include/hdb.h"
47 typedef int (*dispatch_fn_t
) (poll_handle poll_handle
, int fd
, int revents
, void *data
);
51 dispatch_fn_t dispatch_fn
;
55 struct poll_instance
{
56 struct poll_entry
*poll_entries
;
59 struct timerlist timerlist
;
60 void (*serialize_lock_fn
) (void);
61 void (*serialize_unlock_fn
) (void);
65 * All instances in one database
67 static struct hdb_handle_database poll_instance_database
= {
73 poll_handle
poll_create (
74 void (*serialize_lock_fn
) (void),
75 void (*serialize_unlock_fn
) (void))
78 struct poll_instance
*poll_instance
;
81 res
= hdb_handle_create (&poll_instance_database
,
82 sizeof (struct poll_instance
), &handle
);
86 res
= hdb_handle_get (&poll_instance_database
, handle
,
87 (void *)&poll_instance
);
92 poll_instance
->poll_entries
= 0;
93 poll_instance
->ufds
= 0;
94 poll_instance
->poll_entry_count
= 0;
95 poll_instance
->serialize_lock_fn
= serialize_lock_fn
;
96 poll_instance
->serialize_unlock_fn
= serialize_unlock_fn
;
97 timerlist_init (&poll_instance
->timerlist
);
102 hdb_handle_destroy (&poll_instance_database
, handle
);
108 int poll_destroy (poll_handle handle
)
110 struct poll_instance
*poll_instance
;
113 res
= hdb_handle_get (&poll_instance_database
, handle
,
114 (void *)&poll_instance
);
120 if (poll_instance
->poll_entries
) {
121 free (poll_instance
->poll_entries
);
123 if (poll_instance
->ufds
) {
124 free (poll_instance
->ufds
);
127 hdb_handle_destroy (&poll_instance_database
, handle
);
129 hdb_handle_put (&poll_instance_database
, handle
);
135 int poll_dispatch_add (
141 poll_handle poll_handle
,
146 struct poll_instance
*poll_instance
;
147 struct poll_entry
*poll_entries
;
153 res
= hdb_handle_get (&poll_instance_database
, handle
,
154 (void *)&poll_instance
);
160 for (found
= 0, install_pos
= 0; install_pos
< poll_instance
->poll_entry_count
; install_pos
++) {
161 if (poll_instance
->poll_entries
[install_pos
].ufd
.fd
== -1) {
171 poll_entries
= (struct poll_entry
*)realloc (poll_instance
->poll_entries
,
172 (poll_instance
->poll_entry_count
+ 1) *
173 sizeof (struct poll_entry
));
174 if (poll_entries
== NULL
) {
178 poll_instance
->poll_entries
= poll_entries
;
180 ufds
= (struct pollfd
*)realloc (poll_instance
->ufds
,
181 (poll_instance
->poll_entry_count
+ 1) *
182 sizeof (struct pollfd
));
187 poll_instance
->ufds
= ufds
;
189 poll_instance
->poll_entry_count
+= 1;
190 install_pos
= poll_instance
->poll_entry_count
- 1;
194 * Install new dispatch handler
196 poll_instance
->poll_entries
[install_pos
].ufd
.fd
= fd
;
197 poll_instance
->poll_entries
[install_pos
].ufd
.events
= events
;
198 poll_instance
->poll_entries
[install_pos
].ufd
.revents
= 0;
199 poll_instance
->poll_entries
[install_pos
].dispatch_fn
= dispatch_fn
;
200 poll_instance
->poll_entries
[install_pos
].data
= data
;
203 hdb_handle_put (&poll_instance_database
, handle
);
209 int poll_dispatch_modify (
214 poll_handle poll_handle
,
219 struct poll_instance
*poll_instance
;
223 res
= hdb_handle_get (&poll_instance_database
, handle
,
224 (void *)&poll_instance
);
231 * Find file descriptor to modify events and dispatch function
233 for (i
= 0; i
< poll_instance
->poll_entry_count
; i
++) {
234 if (poll_instance
->poll_entries
[i
].ufd
.fd
== fd
) {
235 poll_instance
->poll_entries
[i
].ufd
.events
= events
;
236 poll_instance
->poll_entries
[i
].dispatch_fn
= dispatch_fn
;
245 hdb_handle_put (&poll_instance_database
, handle
);
251 int poll_dispatch_delete (
255 struct poll_instance
*poll_instance
;
259 res
= hdb_handle_get (&poll_instance_database
, handle
,
260 (void *)&poll_instance
);
267 * Find dispatch fd to delete
270 for (i
= 0; i
< poll_instance
->poll_entry_count
; i
++) {
271 if (poll_instance
->poll_entries
[i
].ufd
.fd
== fd
) {
272 poll_instance
->poll_entries
[i
].ufd
.fd
= -1;
273 poll_instance
->poll_entries
[i
].ufd
.revents
= 0;
279 hdb_handle_put (&poll_instance_database
, handle
);
287 int msec_duration
, void *data
,
288 void (*timer_fn
) (void *data
),
289 poll_timer_handle
*timer_handle_out
)
291 struct poll_instance
*poll_instance
;
294 res
= hdb_handle_get (&poll_instance_database
, handle
,
295 (void *)&poll_instance
);
302 if (timer_handle_out
== 0) {
306 timerlist_add_duration (&poll_instance
->timerlist
,
307 timer_fn
, data
, ((unsigned long long)msec_duration
) * 1000000ULL, timer_handle_out
);
309 hdb_handle_put (&poll_instance_database
, handle
);
314 int poll_timer_delete (
316 poll_timer_handle timer_handle
)
318 struct poll_instance
*poll_instance
;
321 if (timer_handle
== 0) {
324 res
= hdb_handle_get (&poll_instance_database
, handle
,
325 (void *)&poll_instance
);
331 timerlist_del (&poll_instance
->timerlist
, (void *)timer_handle
);
333 hdb_handle_put (&poll_instance_database
, handle
);
342 struct poll_instance
*poll_instance
;
344 unsigned long long expire_timeout_msec
= -1;
346 int poll_entry_count
;
348 res
= hdb_handle_get (&poll_instance_database
, handle
,
349 (void *)&poll_instance
);
355 for (i
= 0; i
< poll_instance
->poll_entry_count
; i
++) {
356 memcpy (&poll_instance
->ufds
[i
],
357 &poll_instance
->poll_entries
[i
].ufd
,
358 sizeof (struct pollfd
));
360 expire_timeout_msec
= timerlist_msec_duration_to_expire (&poll_instance
->timerlist
);
362 if (expire_timeout_msec
!= -1 && expire_timeout_msec
> 0xFFFFFFFF) {
363 expire_timeout_msec
= 0xFFFFFFFE;
367 res
= poll (poll_instance
->ufds
,
368 poll_instance
->poll_entry_count
, expire_timeout_msec
);
369 if (errno
== EINTR
&& res
== -1) {
376 poll_entry_count
= poll_instance
->poll_entry_count
;
377 for (i
= 0; i
< poll_entry_count
; i
++) {
378 if (poll_instance
->ufds
[i
].fd
!= -1 &&
379 poll_instance
->ufds
[i
].revents
) {
381 poll_instance
->serialize_lock_fn();
382 res
= poll_instance
->poll_entries
[i
].dispatch_fn (handle
,
383 poll_instance
->ufds
[i
].fd
,
384 poll_instance
->ufds
[i
].revents
,
385 poll_instance
->poll_entries
[i
].data
);
387 poll_instance
->serialize_unlock_fn();
389 * Remove dispatch functions that return -1
392 poll_instance
->poll_entries
[i
].ufd
.fd
= -1; /* empty entry */
396 poll_instance
->serialize_lock_fn();
397 timerlist_expire (&poll_instance
->timerlist
);
398 poll_instance
->serialize_unlock_fn();
401 hdb_handle_put (&poll_instance_database
, handle
);
410 void poll_print_state (
414 struct poll_instance
*poll_instance
;
417 res
= hdb_handle_get (&poll_instance_database
, handle
,
418 (void *)&poll_instance
);
424 for (i
= 0; i
< poll_instance
->poll_entry_count
; i
++) {
425 if (poll_instance
->poll_entries
[i
].ufd
.fd
== fd
) {
426 printf ("fd %d\n", poll_instance
->poll_entries
[i
].ufd
.fd
);
427 printf ("events %d\n", poll_instance
->poll_entries
[i
].ufd
.events
);
428 printf ("dispatch_fn %p\n", poll_instance
->poll_entries
[i
].dispatch_fn
);