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

#include <assert.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>

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


/* thread queues */

struct wait_queue_entry
{
    struct wait_queue_entry *next;
    struct wait_queue_entry *prev;
    struct object           *obj;
    struct thread           *thread;
};

struct thread_wait
{
    int                     count;      /* count of objects */
    int                     flags;
    struct timeval          timeout;
    struct wait_queue_entry queues[1];
};


/* thread operations */

static void dump_thread( struct object *obj, int verbose );
static int thread_signaled( struct object *obj, struct thread *thread );
static int thread_satisfied( struct object *obj, struct thread *thread );
static void destroy_thread( struct object *obj );

static const struct object_ops thread_ops =
{
    dump_thread,
    thread_signaled,
    thread_satisfied,
    destroy_thread
};

static struct thread *first_thread;


/* create a new thread */
struct thread *create_thread( int fd, void *pid, int *thread_handle,
                              int *process_handle )
{
    struct thread *thread;
    struct process *process;

    if (!(thread = mem_alloc( sizeof(*thread) ))) return NULL;

    if (pid) process = get_process_from_id( pid );
    else process = create_process();
    if (!process)
    {
        free( thread );
        return NULL;
    }

    init_object( &thread->obj, &thread_ops, NULL );
    thread->client_fd = fd;
    thread->process   = process;
    thread->unix_pid  = 0;  /* not known yet */
    thread->name      = NULL;
    thread->mutex     = NULL;
    thread->wait      = NULL;
    thread->error     = 0;
    thread->state     = STARTING;
    thread->exit_code = 0x103;  /* STILL_ACTIVE */
    thread->next      = first_thread;
    thread->prev      = NULL;

    if (first_thread) first_thread->prev = thread;
    first_thread = thread;
    add_process_thread( process, thread );

    *thread_handle = *process_handle = -1;
    if (current)
    {
        if ((*thread_handle = alloc_handle( current->process, thread,
                                            THREAD_ALL_ACCESS, 0 )) == -1)
            goto error;
    }
    if (current && !pid)
    {
        if ((*process_handle = alloc_handle( current->process, process,
                                             PROCESS_ALL_ACCESS, 0 )) == -1)
            goto error;
    }

    if (add_client( fd, thread ) == -1) goto error;

    return thread;

 error:
    if (current)
    {
        close_handle( current->process, *thread_handle );
        close_handle( current->process, *process_handle );
    }
    remove_process_thread( process, thread );
    release_object( thread );
    return NULL;
}

/* destroy a thread when its refcount is 0 */
static void destroy_thread( struct object *obj )
{
    struct thread *thread = (struct thread *)obj;
    assert( obj->ops == &thread_ops );

    release_object( thread->process );
    if (thread->next) thread->next->prev = thread->prev;
    if (thread->prev) thread->prev->next = thread->next;
    else first_thread = thread->next;
    if (thread->name) free( thread->name );
    if (debug_level) memset( thread, 0xaa, sizeof(thread) );  /* catch errors */
    free( thread );
}

/* dump a thread on stdout for debugging purposes */
static void dump_thread( struct object *obj, int verbose )
{
    struct thread *thread = (struct thread *)obj;
    assert( obj->ops == &thread_ops );

    printf( "Thread pid=%d fd=%d name='%s'\n",
            thread->unix_pid, thread->client_fd, thread->name );
}

static int thread_signaled( struct object *obj, struct thread *thread )
{
    struct thread *mythread = (struct thread *)obj;
    return (mythread->state == TERMINATED);
}

static int thread_satisfied( struct object *obj, struct thread *thread )
{
    return 0;
}

/* get a thread pointer from a thread id (and increment the refcount) */
struct thread *get_thread_from_id( void *id )
{
    struct thread *t = first_thread;
    while (t && (t != id)) t = t->next;
    if (t) grab_object( t );
    return t;
}

/* get a thread from a handle (and increment the refcount) */
struct thread *get_thread_from_handle( int handle, unsigned int access )
{
    return (struct thread *)get_handle_obj( current->process, handle,
                                            access, &thread_ops );
}

/* get all information about a thread */
void get_thread_info( struct thread *thread,
                      struct get_thread_info_reply *reply )
{
    reply->pid       = thread;
    reply->exit_code = thread->exit_code;
}

/* send a reply to a thread */
int send_reply( struct thread *thread, int pass_fd, int n,
                ... /* arg_1, len_1, ..., arg_n, len_n */ )
{
    struct iovec vec[16];
    va_list args;
    int i;

    assert( n < 16 );
    va_start( args, n );
    for (i = 0; i < n; i++)
    {
        vec[i].iov_base = va_arg( args, void * );
        vec[i].iov_len  = va_arg( args, int );
    }
    va_end( args );
    return send_reply_v( thread->client_fd, thread->error, pass_fd, vec, n );
}

/* add a thread to an object wait queue; return 1 if OK, 0 on error */
static void add_queue( struct object *obj, struct wait_queue_entry *entry )
{
    entry->obj    = obj;
    entry->prev   = obj->tail;
    entry->next   = NULL;
    if (obj->tail) obj->tail->next = entry;
    else obj->head = entry;
    obj->tail = entry;
}

/* remove a thread from an object wait queue */
static void remove_queue( struct wait_queue_entry *entry )
{
    struct object *obj = entry->obj;

    if (entry->next) entry->next->prev = entry->prev;
    else obj->tail = entry->prev;
    if (entry->prev) entry->prev->next = entry->next;
    else obj->head = entry->next;
    release_object( obj );
}

/* finish waiting */
static void end_wait( struct thread *thread )
{
    struct thread_wait *wait = thread->wait;
    struct wait_queue_entry *entry;
    int i;

    assert( wait );
    for (i = 0, entry = wait->queues; i < wait->count; i++)
        remove_queue( entry++ );
    if (wait->flags & SELECT_TIMEOUT) set_timeout( thread->client_fd, NULL );
    free( wait );
    thread->wait = NULL;
}

/* build the thread wait structure */
static int wait_on( struct thread *thread, int count,
                    int *handles, int flags, int timeout )
{
    struct thread_wait *wait;
    struct wait_queue_entry *entry;
    struct object *obj;
    int i;

    if ((count < 0) || (count > MAXIMUM_WAIT_OBJECTS))
    {
        SET_ERROR( ERROR_INVALID_PARAMETER );
        return 0;
    }
    if (!(wait = mem_alloc( sizeof(*wait) + (count-1) * sizeof(*entry) ))) return 0;
    thread->wait  = wait;
    wait->count   = count;
    wait->flags   = flags;
    if (flags & SELECT_TIMEOUT)
    {
        gettimeofday( &wait->timeout, 0 );
        if (timeout)
        {
            wait->timeout.tv_usec += (timeout % 1000) * 1000;
            if (wait->timeout.tv_usec >= 1000000)
            {
                wait->timeout.tv_usec -= 1000000;
                wait->timeout.tv_sec++;
            }
            wait->timeout.tv_sec += timeout / 1000;
        }
    }

    for (i = 0, entry = wait->queues; i < count; i++, entry++)
    {
        if (!(obj = get_handle_obj( thread->process, handles[i],
                                    SYNCHRONIZE, NULL )))
        {
            wait->count = i - 1;
            end_wait( thread );
            return 0;
        }
        entry->thread = thread;
        add_queue( obj, entry );
    }
    return 1;
}

/* check if the thread waiting condition is satisfied */
static int check_wait( struct thread *thread, int *signaled )
{
    int i;
    struct thread_wait *wait = thread->wait;
    struct wait_queue_entry *entry = wait->queues;
    struct timeval now;

    assert( wait );
    if (wait->flags & SELECT_ALL)
    {
        for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
            if (!entry->obj->ops->signaled( entry->obj, thread )) goto check_timeout;
        /* Wait satisfied: tell it to all objects */
        *signaled = 0;
        for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
            if (entry->obj->ops->satisfied( entry->obj, thread ))
                *signaled = STATUS_ABANDONED_WAIT_0;
        return 1;
    }
    else
    {
        for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
        {
            if (!entry->obj->ops->signaled( entry->obj, thread )) continue;
            /* Wait satisfied: tell it to the object */
            *signaled = i;
            if (entry->obj->ops->satisfied( entry->obj, thread ))
                *signaled += STATUS_ABANDONED_WAIT_0;
            return 1;
        }
    }
 check_timeout:
    if (!(wait->flags & SELECT_TIMEOUT)) return 0;
    gettimeofday( &now, NULL );
    if ((now.tv_sec > wait->timeout.tv_sec) ||
        ((now.tv_sec == wait->timeout.tv_sec) &&
         (now.tv_usec >= wait->timeout.tv_usec)))
    {
        *signaled = STATUS_TIMEOUT;
        return 1;
    }
    return 0;
}

/* sleep on a list of objects */
void sleep_on( struct thread *thread, int count, int *handles, int flags, int timeout )
{
    struct select_reply reply;

    assert( !thread->wait );
    reply.signaled = -1;
    if (!wait_on( thread, count, handles, flags, timeout )) goto done;
    if (!check_wait( thread, &reply.signaled ))
    {
        /* we need to wait */
        if (flags & SELECT_TIMEOUT)
            set_timeout( thread->client_fd, &thread->wait->timeout );
        return;
    }
    end_wait( thread );
 done:
    send_reply( thread, -1, 1, &reply, sizeof(reply) );
}

/* attempt to wake up a thread */
/* return 1 if OK, 0 if the wait condition is still not satisfied */
static int wake_thread( struct thread *thread )
{
    struct select_reply reply;

    if (!check_wait( thread, &reply.signaled )) return 0;
    end_wait( thread );
    send_reply( thread, -1, 1, &reply, sizeof(reply) );
    return 1;
}

/* timeout for the current thread */
void thread_timeout(void)
{
    struct select_reply reply;

    assert( current->wait );

    reply.signaled = STATUS_TIMEOUT;
    end_wait( current );
    send_reply( current, -1, 1, &reply, sizeof(reply) );
}

/* attempt to wake threads sleeping on the object wait queue */
void wake_up( struct object *obj, int max )
{
    struct wait_queue_entry *entry = obj->head;

    while (entry)
    {
        struct wait_queue_entry *next = entry->next;
        if (wake_thread( entry->thread ))
        {
            if (max && !--max) break;
        }
        entry = next;
    }
}

/* kill a thread on the spot */
void kill_thread( struct thread *thread, int exit_code )
{
    if (thread->state == TERMINATED) return;  /* already killed */
    if (thread->unix_pid) kill( thread->unix_pid, SIGTERM );
    remove_client( thread->client_fd, exit_code ); /* this will call thread_killed */
}

/* a thread has been killed */
void thread_killed( struct thread *thread, int exit_code )
{
    thread->state = TERMINATED;
    thread->exit_code = exit_code;
    if (thread->wait) end_wait( thread );
    abandon_mutexes( thread );
    remove_process_thread( thread->process, thread );
    wake_up( &thread->obj, 0 );
    release_object( thread );
}
