1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (c) 2002 Cray Inc.
5 * Copyright (c) 2002 Eric Hoffman
7 * This file is part of Lustre, http://www.lustre.org.
9 * Lustre is free software; you can redistribute it and/or
10 * modify it under the terms of version 2 of the GNU General Public
11 * License as published by the Free Software Foundation.
13 * Lustre is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with Lustre; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 * Provides a general mechanism for registering and dispatching
25 * io events through the select system call.
29 #include <sys/filio.h>
31 #include <sys/ioctl.h>
35 #include <sys/types.h>
41 static struct timeval beginning_of_epoch;
42 static io_handler io_handlers;
46 * Return: the current time in canonical units: a 64 bit number
47 * where the most significant 32 bits contains the number
48 * of seconds, and the least signficant a count of (1/(2^32))ths
53 struct timeval result;
55 gettimeofday(&result,0);
56 return((((unsigned long long)result.tv_sec)<<32)|
57 (((unsigned long long)result.tv_usec)<<32)/1000000);
61 /* Function: register_io_handler
62 * Arguments: fd: the file descriptor of interest
63 * type: a mask of READ_HANDLER, WRITE_HANDLER, EXCEPTION_HANDLER
64 * function: a function to call when io is available on fd
65 * arg: an opaque correlator to return to the handler
66 * Returns: a pointer to the io_handler structure
68 io_handler register_io_handler(int fd,
70 int (*function)(void *),
73 io_handler i=(io_handler)malloc(sizeof(struct io_handler));
80 if ((i->next=io_handlers)) i->next->last=&i->next;
86 /* Function: remove_io_handler
87 * Arguments: i: a pointer to the handler to stop servicing
89 * remove_io_handler() doesn't actually free the handler, due
90 * to reentrancy problems. it just marks the handler for
91 * later cleanup by the blocking function.
93 void remove_io_handler (io_handler i)
98 static void set_flag(io_handler n,fd_set *fds)
100 if (n->type & READ_HANDLER) FD_SET(n->fd,fds);
101 if (n->type & WRITE_HANDLER) FD_SET(n->fd,fds+1);
102 if (n->type & EXCEPTION_HANDLER) FD_SET(n->fd,fds+2);
106 /* Function: select_timer_block
107 * Arguments: until: an absolute time when the select should return
109 * This function dispatches the various file descriptors' handler
110 * functions, if the kernel indicates there is io available.
112 void select_timer_block(when until)
115 struct timeval timeout;
116 struct timeval *timeout_pointer;
121 /* TODO: loop until the entire interval is expired*/
123 when interval=until-now();
124 timeout.tv_sec=(interval>>32);
125 timeout.tv_usec=((interval<<32)/1000000)>>32;
126 timeout_pointer=&timeout;
127 } else timeout_pointer=0;
132 for (k=&io_handlers;*k;){
143 result=select(FD_SETSIZE,fds,fds+1,fds+2,timeout_pointer);
146 for (j=io_handlers;j;j=j->next){
147 if (!(j->disabled) &&
148 ((FD_ISSET(j->fd,fds) && (j->type & READ_HANDLER)) ||
149 (FD_ISSET(j->fd,fds+1) && (j->type & WRITE_HANDLER)) ||
150 (FD_ISSET(j->fd,fds+2) && (j->type & EXCEPTION_HANDLER)))){
151 if (!(*j->function)(j->argument))
157 /* Function: init_unix_timer()
158 * is called to initialize the library
160 void init_unix_timer()
163 gettimeofday(&beginning_of_epoch, 0);
164 initialize_timer(select_timer_block);