Headers Index Help Within this page: Functions Constants Variables
This package contains a set of functions to manipulate a list of pollable fds. It will also manage the associated threads if the calling program is a multi-threaded design based round a single poll() based thread dispatcher.
All the information required by the package is kept in a single instance of the FDL structure. There is one one of these in each running program. It contains parallel arrays of pollfds, listener flags and TCB structures. A TCB holds details of an active thread. Elements in the arrays are found be using the fd of an open file or socket as the key. Only one entry in the listener array is TRUE: this identifies the listener fd. The size of the arrays are set at compile time by the MAXFD constant, which is currently set to 50.
NOTE: Don't change MAXFD without recompiling the package.
The contents of the FDL structure should not be accessed directly by the calling program: use the fdlist_xxxx() functions for all manipulation of its contents.
This collection of functions is compiled to form part of the libenviron.a library, which must be linked if any of of its constituent functions are called.
The calling programs should include fdlist.h and must be linked using -lenviron.
environ - C programming support functions
This program is free software; you can redistribute it and/or
modify it under the terms of the Lesser GNU General Public License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the Lesser GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Copyright (C) 2005 Martin C Gregorie
Contact Martin Gregorie at martin@gregorie.org
Include files defined in the header, fdlist.h, are shown in italics.
#include <semaphore.h>
#include <pthread.h>
#include <fdlist.h>
int fdlist_add(FDL *pl, int fd, int listener_flag);
Add a file fd to the list of polled files. listener_flag is set to be TRUE if this file is the socket listener for this process. It returns ADDED on success, ON_LIMIT if the fd could not be added because the FDL arrays are full, or ERROR if some other problem ocurred.
In: fdlist.c
Return to the top
#include <semaphore.h>
#include <pthread.h>
#include <fdlist.h>
FDL *fdlist_create(void);
Create and initialise the FDL structure. Returns a pointer to the structure on success and null on error. Failure to acquire memory to hold the FDL structure or its components will cause the program to abandon with a message that it can't allocate the required amount of memory.
In: fdlist.c
Return to the top
#include <semaphore.h>
#include <pthread.h>
#include <fdlist.h>
void fdlist_debug(int d);
This function sets debugging level for the package. A setting of zero turns tracing off. A value of 1 turns on function call tracing as an aid to debugging the calling program. Values of 2 or greater turn on a limited amount of internal function tracing.
NOTE: Calls to fdlist_fds() and fdlist_size() are not traced below a debug level of 2 because this output can be confusing when the calling program is being debugged.
In: fdlist.c
Return to the top
#include <semaphore.h>
#include <pthread.h>
#include <fdlist.h>
char *fdlist_decode(short revents);
Decode the event flags in revents and return a string containing the result. This is used internally by fdlist_xxx() functions that return or manipulate event flags. It is a diagnostic tool.
In: fdlist.c
Return to the top
#include <semaphore.h>
#include <pthread.h>
#include <fdlist.h>
int fdlist_del(FDL *pl, int fd);
Remove a file fd from the fd list. Returns -1 on error or zero on success.
In: fdlist.c
Return to the top
#include <semaphore.h>
#include <pthread.h>
#include <fdlist.h>
struct pollfd *fdlist_fds(FDL *pl);
Return a pointer to the list of fds for use by poll(). Returns null if the operation failed: this will be because the FDL structure has not been created.
This function is not traced below a debugging level of 2.
In: fdlist.c
Return to the top
#include <semaphore.h>
#include <pthread.h>
#include <fdlist.h>
TCB *fdlist_get_tcb_ref(FDL *pl, int fd);
Retrieve a pointer to the thread control block for the given fd. Returns the pointer on success and null if the fd could not be found.
In: fdlist.c
Return to the top
#include <semaphore.h>
#include <pthread.h>
#include <fdlist.h>
int fdlist_getevents(FDL *pl, int fd, short *evflags);
Retrieve the event flags mask for an existing fd list entry. *evflags points to a short that will receive the flags set by the current event for fd. Returns -1 on error or zero on success.
In: fdlist.c
Return to the top
#include <semaphore.h>
#include <pthread.h>
#include <fdlist.h>
short fdlist_geteventtype(FDL *pl, int fd);
Retrieve the current event list for the fd in order to see why it caused poll() to exit. The events are cleared in preparation for the next call on poll().
A return value of zero means that either the fd does not match anything in the FDL or that fd refers to a file that has not raised any events.
In: fdlist.c
Return to the top
#include <semaphore.h>
#include <pthread.h>
#include <fdlist.h>
int fdlist_getfd(FDL *pl);
Find an fd that caused poll() to exit. Returns -1 if no file has events notified or the fd is invalid.
After poll() has exited this function should be called repeatedly until it returns -1. This will find each file that caused poll() to exit. It is the central run-time function in this package:
poll(fdlist_fds(fdl), fdlist_size(fdl), timeout); while ((fd = fdlist_getfd(fdl)) != -1) { events = fdlist_geteventtype(fdl, fd); ...process the events.... }The above, shorn of its error handling, shows how a number of the fdlist_xxx() functions should be used.
In: fdlist.c
Return to the top
#include <semaphore.h>
#include <pthread.h>
#include <fdlist.h>
int fdlist_islistener(FDL *pl, int fd);
Returns TRUE if the fd is the socket listener for this process.
In: fdlist.c
Return to the top
#include <semaphore.h>
#include <pthread.h>
#include <fdlist.h>
int fdlist_nextopen(FDL *pl);
Returns an fd if there is an open file in the list that is not the listener. Returns -1 if there isn't any such file.
This is primarily used during a forced shutdown to find all open sockets and close them in an orderly fashion. It should be called repeatedly until it returns -1, dealing with each open file in turn.
In: fdlist.c
Return to the top
#include <semaphore.h>
#include <pthread.h>
#include <fdlist.h>
FDL *fdlist_release(FDL *pl);
Deallocate the FDL structure and release its storage space. It returns null.
In: fdlist.c
Return to the top
#include <semaphore.h>
#include <pthread.h>
#include <fdlist.h>
int fdlist_setevents(FDL *pl, int fd, short evflags);
Set the event flags mask in an existing fd list entry. Used primarily to turn the POLLOUT flag on when data is available to write and off again when it is exhausted. The value in evflags replaces the event flag mask for the specified fd. Returns -1 on error or zero on success.
In: fdlist.c
Return to the top
#include <semaphore.h>
#include <pthread.h>
#include <fdlist.h>
int fdlist_size(FDL *pl);
Return the number of allocated fds for use by poll(). It returns -1 if the FDL structure has not been created.
This function is not traced below a debugging level of 2.
In: fdlist.c
Return to the topADDED | #define ADDED 0 |
CONNECTION | #define CONNECTION 0 |
ERROR | #define ERROR 2 |
FALSE | #define FALSE 0 |
LISTENER | #define LISTENER 1 |
MAXFDS | #define MAXFDS 50 |
ON_LIMIT | #define ON_LIMIT 1 |
TRUE | #define TRUE 1 |
FDL | typedef struct fdb { int count; struct pollfd fds[MAXFDS]; int listener[MAXFDS]; TCB tcb[MAXFDS]; } FDL; |
TCB | typedef struct thread_control_block { int fd; sem_t *sem_id; pthread_t *thread_id; int debug; } TCB; |