/*
 * Server-side support for async i/o operations
 *
 * Copyright (C) 1998 Alexandre Julliard
 * Copyright (C) 2000 Mike McCormack
 *
 * TODO:
 *  Fix up WaitCommEvent operations. Currently only EV_RXCHAR is supported.
 *    This may require modifications to the linux kernel to enable select
 *    to wait on Modem Status Register deltas. (delta DCD, CTS, DSR or RING)
 *
 */

#include "config.h"

#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#ifdef HAVE_SYS_ERRNO_H
#include <sys/errno.h>
#endif
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <utime.h>
#include <termios.h>
#include <sys/ioctl.h>

#include "winerror.h"
#include "winbase.h"

#include "handle.h"
#include "thread.h"
#include "request.h"

struct async 
{
    struct object           obj;
    void                   *client_overlapped;
    int                     type;
    int                     result;
    int                     count;
    int                     eventmask;
    struct async           *next;
    struct timeout_user    *timeout;
    struct wait_queue_entry wait;
    void                   *buffer;
    void                   *func;
    struct thread          *thread;
    struct object          *file;
};

static void async_dump( struct object *obj, int verbose );
static void async_destroy( struct object *obj );
static int async_get_poll_events( struct object *obj );
static int async_get_read_fd( struct object *obj );
static int async_get_write_fd( struct object *obj );
static int async_get_info( struct object *obj, struct get_file_info_request *req );
static void async_poll_event( struct object *obj, int event );

static const struct object_ops async_ops =
{
    sizeof(struct async),         /* size */
    async_dump,                   /* dump */
    default_poll_add_queue,       /* add_queue */
    default_poll_remove_queue,    /* remove_queue */
    default_poll_signaled,        /* signaled */
    no_satisfied,                 /* satisfied */
    async_get_poll_events,        /* get_poll_events */
    async_poll_event,             /* poll_event */
    async_get_read_fd,            /* get_read_fd */
    async_get_write_fd,           /* get_write_fd */
    no_flush,                     /* flush */
    async_get_info,               /* get_file_info */
    async_destroy                 /* destroy */
};

static void async_dump( struct object *obj, int verbose )
{
    struct async *ov = (struct async *)obj;

    assert( obj->ops == &async_ops );

    fprintf( stderr, "async: overlapped %p %s\n", 
                 ov->client_overlapped, ov->timeout?"with timeout":"");
}

/* same as file_destroy, but don't delete comm ports */
static void async_destroy( struct object *obj )
{
    struct async *ov = (struct async *)obj;
    assert( obj->ops == &async_ops );

    if(ov->timeout)
        remove_timeout_user(ov->timeout);
    ov->timeout = NULL;
}

struct async *get_async_obj( struct process *process, int handle, unsigned int access )
{
    return (struct async *)get_handle_obj( process, handle, access, &async_ops );
}

static int async_get_poll_events( struct object *obj )
{
    struct async *ov = (struct async *)obj;
    assert( obj->ops == &async_ops );

    /* FIXME: this should be a function pointer */
    return serial_async_get_poll_events(ov);
}

static int async_get_read_fd( struct object *obj )
{
    struct async *async = (struct async *)obj;
    assert( obj->ops == &async_ops );
    return dup( async->obj.fd );
}

static int async_get_write_fd( struct object *obj )
{
    struct async *async = (struct async *)obj;
    assert( obj->ops == &async_ops );
    return dup( async->obj.fd );
}

static int async_get_info( struct object *obj, struct get_file_info_request *req ) {
    assert( obj->ops == &async_ops );
    req->type        = FILE_TYPE_CHAR;
    req->attr        = 0;
    req->access_time = 0;
    req->write_time  = 0;
    req->size_high   = 0;
    req->size_low    = 0;
    req->links       = 0;
    req->index_high  = 0;
    req->index_low   = 0;
    req->serial      = 0;
    return 1;
}

/* data access functions */
int async_type(struct async *ov)
{
    return ov->type;
}

int async_count(struct async *ov)
{
    return ov->count;
}

int async_get_eventmask(struct async *ov)
{
    return ov->eventmask;
}

int async_set_eventmask(struct async *ov, int eventmask)
{
    return ov->eventmask = eventmask;
}

DECL_HANDLER(create_async)
{
    struct object *obj;
    struct async *ov = NULL;
    int fd;

    req->ov_handle = -1;
    if (!(obj = get_handle_obj( current->process, req->file_handle, 0, NULL)) )
        return;

    fd = dup(obj->fd);
    if(fd<0)
    {
        release_object(obj);
        set_error(STATUS_UNSUCCESSFUL);
        return;
    }

    if(0>fcntl(fd, F_SETFL, O_NONBLOCK))
    {
        release_object(obj);
        set_error(STATUS_UNSUCCESSFUL);
        return;
    }

    ov = alloc_object (&async_ops, fd);
    if(!ov)
    {
        release_object(obj);
        set_error(STATUS_UNSUCCESSFUL);
        return;
    }

    ov->client_overlapped = req->overlapped;
    ov->next    = NULL;
    ov->timeout = NULL;
    ov->type    = req->type;
    ov->thread  = current;
    ov->func    = req->func;
    ov->file    = obj;
    ov->buffer  = req->buffer;
    ov->count   = req->count;

    /* FIXME: this should be a function pointer */
    serial_async_setup(obj,ov);

    ov->obj.ops->add_queue(&ov->obj,&ov->wait);

    req->ov_handle = alloc_handle( current->process, ov, GENERIC_READ|GENERIC_WRITE, 0 );

    release_object(obj);
}

/* handler for async poll() events */
static void async_poll_event( struct object *obj, int event )
{
    struct async *ov = (struct async *) obj;
 
    /* queue an APC in the client thread to do our dirty work */
    ov->obj.ops->remove_queue(&ov->obj,&ov->wait);

    /* FIXME: this should be a function pointer */
    event = serial_async_poll_event(obj,event);

    thread_queue_apc(ov->thread, NULL, ov->func, APC_ASYNC, 3,
                     ov->client_overlapped, ov->buffer, event);
} 

/* handler for async i/o timeouts */
static void overlapped_timeout (void *private)
{
    struct async *ov = (struct async *) private;
 
    ov->obj.ops->remove_queue(&ov->obj,&ov->wait);
 
    thread_queue_apc(ov->thread, NULL, ov->func, APC_ASYNC, 3,
                     ov->client_overlapped,ov->buffer, 0);
}

void async_add_timeout(struct async *ov, int timeout)
{
    struct timeval tv;

    gettimeofday(&tv,0);
    add_timeout(&tv,timeout);
    ov->timeout = add_timeout_user(&tv, overlapped_timeout, ov);
}

DECL_HANDLER(async_result)
{
    struct async *ov;

    if ((ov = get_async_obj( current->process, req->ov_handle, 0 )))
    {
        ov->result = req->result;
        if(ov->result == STATUS_PENDING)
        {
            ov->obj.ops->add_queue(&ov->obj,&ov->wait);
        }
        release_object( ov );
    }
}

