/*
 * Server-side event management
 *
 * Copyright (C) 1998 Alexandre Julliard
 */

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

#include "winerror.h"
#include "winnt.h"
#include "server/process.h"
#include "server/thread.h"

struct event
{
    struct object  obj;             /* object header */
    int            manual_reset;    /* is it a manual reset event? */
    int            signaled;        /* event has been signaled */
};

static void event_dump( struct object *obj, int verbose );
static int event_signaled( struct object *obj, struct thread *thread );
static int event_satisfied( struct object *obj, struct thread *thread );
static void event_destroy( struct object *obj );

static const struct object_ops event_ops =
{
    event_dump,
    add_queue,
    remove_queue,
    event_signaled,
    event_satisfied,
    no_read_fd,
    no_write_fd,
    no_flush,
    no_get_file_info,
    event_destroy
};


struct object *create_event( const char *name, int manual_reset, int initial_state )
{
    struct event *event;

    if (!(event = (struct event *)create_named_object( name, &event_ops, sizeof(*event) )))
        return NULL;
    if (GET_ERROR() != ERROR_ALREADY_EXISTS)
    {
        /* initialize it if it didn't already exist */
        event->manual_reset = manual_reset;
        event->signaled     = initial_state;
    }
    return &event->obj;
}

int open_event( unsigned int access, int inherit, const char *name )
{
    return open_object( name, &event_ops, access, inherit );
}

int pulse_event( int handle )
{
    struct event *event;

    if (!(event = (struct event *)get_handle_obj( current->process, handle,
                                                  EVENT_MODIFY_STATE, &event_ops )))
        return 0;
    event->signaled = 1;
    /* wake up all waiters if manual reset, a single one otherwise */
    wake_up( &event->obj, !event->manual_reset );
    event->signaled = 0;
    release_object( event );
    return 1;
}

int set_event( int handle )
{
    struct event *event;

    if (!(event = (struct event *)get_handle_obj( current->process, handle,
                                                  EVENT_MODIFY_STATE, &event_ops )))
        return 0;
    event->signaled = 1;
    /* wake up all waiters if manual reset, a single one otherwise */
    wake_up( &event->obj, !event->manual_reset );
    release_object( event );
    return 1;
}

int reset_event( int handle )
{
    struct event *event;

    if (!(event = (struct event *)get_handle_obj( current->process, handle,
                                                  EVENT_MODIFY_STATE, &event_ops )))
        return 0;
    event->signaled = 0;
    release_object( event );
    return 1;
}

static void event_dump( struct object *obj, int verbose )
{
    struct event *event = (struct event *)obj;
    assert( obj->ops == &event_ops );
    fprintf( stderr, "Event manual=%d signaled=%d name='%s'\n",
             event->manual_reset, event->signaled,
             get_object_name( &event->obj ) );
}

static int event_signaled( struct object *obj, struct thread *thread )
{
    struct event *event = (struct event *)obj;
    assert( obj->ops == &event_ops );
    return event->signaled;
}

static int event_satisfied( struct object *obj, struct thread *thread )
{
    struct event *event = (struct event *)obj;
    assert( obj->ops == &event_ops );
    /* Reset if it's an auto-reset event */
    if (!event->manual_reset) event->signaled = 0;
    return 0;  /* Not abandoned */
}

static void event_destroy( struct object *obj )
{
    struct event *event = (struct event *)obj;
    assert( obj->ops == &event_ops );
    free( event );
}
