/*
 * Structures and static functions for handling asynchronous I/O.
 *
 * Copyright (C) 2002 Mike McCormack,  Martin Wilck
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/*
 * This file declares static functions.
 * It should only be included by those source files that implement async I/O requests.
 */

#ifndef __WINE_ASYNC_H
#define __WINE_ASYNC_H

#include <thread.h>
#include <ntstatus.h>
#include <wine/server.h>
#include <winternl.h>

struct async_private;

typedef void (*async_handler)(struct async_private *ovp);
typedef void (CALLBACK *async_call_completion_func)(ULONG_PTR data);
typedef DWORD (*async_get_count)(const struct async_private *ovp);
typedef void (*async_cleanup)(struct async_private *ovp);

typedef struct async_ops
{
    async_get_count             get_count;
    async_call_completion_func  call_completion;
    async_cleanup               cleanup;
} async_ops;

typedef struct async_private
{
    struct async_ops*   ops;
    HANDLE              handle;
    HANDLE              event;
    int                 fd;
    async_handler       func;
    int                 type;
    IO_STATUS_BLOCK*    iosb;
    struct async_private* next;
    struct async_private* prev;
} async_private;

/* All functions declared static for Dll separation purposes */
static void CALLBACK call_user_apc( ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3 )
{
    PAPCFUNC func = (PAPCFUNC)arg1;
    func( arg2 );
}

inline static void finish_async( async_private *ovp )
{
    if (ovp->prev)
        ovp->prev->next = ovp->next;
    else
        NtCurrentTeb()->pending_list = ovp->next;

    if (ovp->next)
        ovp->next->prev = ovp->prev;

    ovp->next = ovp->prev = NULL;

    wine_server_release_fd( ovp->handle, ovp->fd );
    if ( ovp->event != INVALID_HANDLE_VALUE )
        NtSetEvent( ovp->event, NULL );

    if ( ovp->ops->call_completion )
        NtQueueApcThread( GetCurrentThread(), call_user_apc, 
                          (ULONG_PTR)ovp->ops->call_completion, (ULONG_PTR)ovp, 0 );
    else
        ovp->ops->cleanup( ovp );
}

inline static NTSTATUS __register_async( async_private *ovp, const DWORD status )
{
    NTSTATUS    ret;

    SERVER_START_REQ( register_async )
    {
        req->handle = ovp->handle;
        req->overlapped = ovp;
        req->type = ovp->type;
        req->count = ovp->ops->get_count( ovp );
        req->status = status;
        ret = wine_server_call( req );
    }
    SERVER_END_REQ;

    if (ret) ovp->iosb->u.Status = ret;

    if ( ovp->iosb->u.Status != STATUS_PENDING )
        finish_async(ovp);

    return ret;
}

inline static NTSTATUS register_old_async( async_private *ovp )
{
    return __register_async(ovp, ovp->iosb->u.Status);
}

inline static NTSTATUS register_new_async( async_private *ovp )
{
    ovp->iosb->u.Status = STATUS_PENDING;

    ovp->next = NtCurrentTeb()->pending_list;
    ovp->prev = NULL;
    if ( ovp->next ) ovp->next->prev = ovp;
    NtCurrentTeb()->pending_list = ovp;

    return __register_async( ovp, STATUS_PENDING );
}

inline static NTSTATUS cancel_async( async_private *ovp )
{
     /* avoid multiple cancellations */
     if ( ovp->iosb->u.Status != STATUS_PENDING )
          return STATUS_SUCCESS;
     ovp->iosb->u.Status = STATUS_CANCELLED;
     return __register_async( ovp, STATUS_CANCELLED );
}

#endif /* __WINE_ASYNC_H */
