/** sockset - socket sets for concurrent event waits */

#ifndef LIBAIO__SELECT_H
#define LIBAIO__SELECT_H

/*!#*/ typedef struct SOCKSET_T sockset_t;

#include <sys/types.h>
#include <sys/time.h>
#include "socket.h"
#include "util.h"


/*** SYNOPSIS */
/*| sockset_t *sset = sockset_get(); */
/*| sockset_add(ss, a); */
/*| sockset_add(ss, b); */
/*| sockset_check(ss); */


/** A set of filedescriptors */

/*!typedef struct {*/ struct SOCKSET_T {
	sock_t *socks; /* Pointer to the first sock_t */

	/* Private use: */
	int fdm; /* max fd */
	fd_set fdr, fdw, fde; /* the sets themselves */
/*!} sockset_t;*/ };


/*+ Functions handling that */

/* Get a cleanly initialized sockset. */
/* Returns the pointer or NULL on failure. */
sockset_t *sockset_get();

/* Add a socket to the sockset */
/* Note that you need to call sock_set_del() when releasing the socket and
 * sockset_notify() to announce any changes in the socket handlers. */
/* Also please note that one socket can be only in a single sockset. */
/* Returns 1 if ok, 0 on failure */
int sockset_add(sockset_t *sockset, sock_t *sock);

/* Remove the socket from the sockset. */
/* Returns 1 if ok, 0 on failure */
int sockset_del(sockset_t *sockset, sock_t *sock);

/* Announce that socket handlers changed in the socket. Note that you
 * typically never need to call this directly if you use the standard
 * socket interface to set handlers. */
/* Returns 1 if ok, 0 on failure */
int sockset_notify(sockset_t *sockset, sock_t *sock);

/* Check sockets in the sockset for events and call the appropriate
 * handlers. */
/* Note that this call will block until an event arrives. */
/* Note that when calling a handler, state is set to SS_READABLE, SS_WRITABLE,
 * or SS_EXCEPTION respectively, _if_ the state was SS_IDLE to begin with. */
/* Returns 1 if ok, 0 on failure */
int sockset_check(sockset_t *sockset);

#endif
