/*
 * Server main select() loop
 *
 * Copyright (C) 1998 Alexandre Julliard
 */

#include <assert.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#include "object.h"

struct timeout_user
{
    struct timeout_user  *next;       /* next in sorted timeout list */
    struct timeout_user  *prev;       /* prev in sorted timeout list */
    struct timeval        when;       /* timeout expiry (absolute time) */
    timeout_callback      callback;   /* callback function */
    void                 *private;    /* callback private data */
};

static struct select_user *users[FD_SETSIZE];  /* users array */
static fd_set read_set, write_set, except_set; /* current select sets */
static int nb_users;                        /* current number of users */
static int max_fd;                          /* max fd in use */
static struct timeout_user *timeout_head;   /* sorted timeouts list head */
static struct timeout_user *timeout_tail;   /* sorted timeouts list tail */


/* register a user */
void register_select_user( struct select_user *user )
{
    assert( !users[user->fd] );

    users[user->fd] = user;
    if (user->fd > max_fd) max_fd = user->fd;
    nb_users++;
}

/* remove a user */
void unregister_select_user( struct select_user *user )
{
    assert( users[user->fd] == user );

    FD_CLR( user->fd, &read_set );
    FD_CLR( user->fd, &write_set );
    FD_CLR( user->fd, &except_set );
    users[user->fd] = NULL;
    if (max_fd == user->fd) while (max_fd && !users[max_fd]) max_fd--;
    nb_users--;
}

/* set the events that select waits for on this fd */
void set_select_events( struct select_user *user, int events )
{
    assert( users[user->fd] == user );
    if (events & READ_EVENT) FD_SET( user->fd, &read_set );
    else FD_CLR( user->fd, &read_set );
    if (events & WRITE_EVENT) FD_SET( user->fd, &write_set );
    else FD_CLR( user->fd, &write_set );
    if (events & EXCEPT_EVENT) FD_SET( user->fd, &except_set );
    else FD_CLR( user->fd, &except_set );
}

/* check if events are pending */
int check_select_events( struct select_user *user, int events )
{
    fd_set read_fds, write_fds, except_fds;
    struct timeval tv = { 0, 0 };

    FD_ZERO( &read_fds );
    FD_ZERO( &write_fds );
    FD_ZERO( &except_fds );
    if (events & READ_EVENT) FD_SET( user->fd, &read_fds );
    if (events & WRITE_EVENT) FD_SET( user->fd, &write_fds );
    if (events & EXCEPT_EVENT) FD_SET( user->fd, &except_fds );
    return select( user->fd + 1, &read_fds, &write_fds, &except_fds, &tv ) > 0;
}

/* add a timeout user */
struct timeout_user *add_timeout_user( struct timeval *when, timeout_callback func, void *private )
{
    struct timeout_user *user;
    struct timeout_user *pos;

    if (!(user = mem_alloc( sizeof(*user) ))) return NULL;
    user->when     = *when;
    user->callback = func;
    user->private  = private;

    /* Now insert it in the linked list */

    for (pos = timeout_head; pos; pos = pos->next)
    {
        if (pos->when.tv_sec > user->when.tv_sec) break;
        if ((pos->when.tv_sec == user->when.tv_sec) &&
            (pos->when.tv_usec > user->when.tv_usec)) break;
    }

    if (pos)  /* insert it before 'pos' */
    {
        if ((user->prev = pos->prev)) user->prev->next = user;
        else timeout_head = user;
        user->next = pos;
        pos->prev = user;
    }
    else  /* insert it at the tail */
    {
        user->next = NULL;
        if (timeout_tail) timeout_tail->next = user;
        else timeout_head = user;
        user->prev = timeout_tail;
        timeout_tail = user;
    }
    return user;
}

/* remove a timeout user */
void remove_timeout_user( struct timeout_user *user )
{
    if (user->next) user->next->prev = user->prev;
    else timeout_tail = user->prev;
    if (user->prev) user->prev->next = user->next;
    else timeout_head = user->next;
    free( user );
}

/* make an absolute timeout value from a relative timeout in milliseconds */
void make_timeout( struct timeval *when, int timeout )
{
    gettimeofday( when, 0 );
    if (!timeout) return;
    if ((when->tv_usec += (timeout % 1000) * 1000) >= 1000000)
    {
        when->tv_usec -= 1000000;
        when->tv_sec++;
    }
    when->tv_sec += timeout / 1000;
}

/* handle an expired timeout */
static void handle_timeout( struct timeout_user *user )
{
    if (user->next) user->next->prev = user->prev;
    else timeout_tail = user->prev;
    if (user->prev) user->prev->next = user->next;
    else timeout_head = user->next;
    user->callback( user->private );
    free( user );
}

#ifdef DEBUG_OBJECTS
static int do_dump_objects;

/* SIGHUP handler */
static void sighup()
{
    do_dump_objects = 1;
}
#endif

/* server main loop */
void select_loop(void)
{
    int i, ret;

    setsid();
    signal( SIGPIPE, SIG_IGN );
#ifdef DEBUG_OBJECTS
    signal( SIGHUP, sighup );
#endif

    while (nb_users)
    {
        fd_set read = read_set, write = write_set, except = except_set;
        if (timeout_head)
        {
            struct timeval tv, now;
            gettimeofday( &now, NULL );
            if ((timeout_head->when.tv_sec < now.tv_sec) ||
                ((timeout_head->when.tv_sec == now.tv_sec) &&
                 (timeout_head->when.tv_usec < now.tv_usec)))
            {
                handle_timeout( timeout_head );
                continue;
            }
            tv.tv_sec = timeout_head->when.tv_sec - now.tv_sec;
            if ((tv.tv_usec = timeout_head->when.tv_usec - now.tv_usec) < 0)
            {
                tv.tv_usec += 1000000;
                tv.tv_sec--;
            }
#if 0
            printf( "select: " );
            for (i = 0; i <= max_fd; i++) printf( "%c", FD_ISSET( i, &read_set ) ? 'r' :
                                                  (FD_ISSET( i, &write_set ) ? 'w' : '-') );
            printf( " timeout %d.%06d\n", tv.tv_sec, tv.tv_usec );
#endif
            ret = select( max_fd + 1, &read, &write, &except, &tv );
        }
        else  /* no timeout */
        {
#if 0
            printf( "select: " );
            for (i = 0; i <= max_fd; i++) printf( "%c", FD_ISSET( i, &read_set ) ? 'r' :
                                                  (FD_ISSET( i, &write_set ) ? 'w' : '-') );
            printf( " no timeout\n" );
#endif
            ret = select( max_fd + 1, &read, &write, &except, NULL );
        }

        if (!ret) continue;
        if (ret == -1) {
            if (errno == EINTR)
            {
#ifdef DEBUG_OBJECTS
                if (do_dump_objects) dump_objects();
                do_dump_objects = 0;
#endif
                continue;
            }
            perror("select");
        }

        for (i = 0; i <= max_fd; i++)
        {
            int event = 0;
            if (FD_ISSET( i, &except )) event |= EXCEPT_EVENT;
            if (FD_ISSET( i, &write ))  event |= WRITE_EVENT;
            if (FD_ISSET( i, &read ))   event |= READ_EVENT;

            /* Note: users[i] might be NULL here, because an event routine
               called in an earlier pass of this loop might have removed 
               the current user ... */
            if (event && users[i]) 
                users[i]->func( event, users[i]->private );
        }
    }
}
