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

#include <assert.h>
#include <limits.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>

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

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

/* reserved handle access rights */
#define RESERVED_SHIFT         25
#define RESERVED_INHERIT       (HANDLE_FLAG_INHERIT << RESERVED_SHIFT)
#define RESERVED_CLOSE_PROTECT (HANDLE_FLAG_PROTECT_FROM_CLOSE << RESERVED_SHIFT)
#define RESERVED_ALL           (RESERVED_INHERIT | RESERVED_CLOSE_PROTECT)

struct handle_entry
{
    struct object *ptr;
    unsigned int   access;
};

/* process structure; not much for now... */

struct process
{
    struct object        obj;             /* object header */
    struct process      *next;            /* system-wide process list */
    struct process      *prev;
    struct thread       *thread_list;     /* head of the thread list */
    struct handle_entry *entries;         /* handle entry table */
    int                  handle_count;    /* nb of allocated handle entries */
    int                  handle_last;     /* last used handle entry */
    int                  exit_code;       /* process exit code */
    int                  running_threads; /* number of threads running in this process */
    struct timeval       start_time;      /* absolute time at process start */
    struct timeval       end_time;        /* absolute time at process end */
};

static struct process *first_process;

#define MIN_HANDLE_ENTRIES  32

/* process operations */

static void dump_process( struct object *obj, int verbose );
static int process_signaled( struct object *obj, struct thread *thread );
static int process_satisfied( struct object *obj, struct thread *thread );
static void destroy_process( struct object *obj );
static void free_handles( struct process *process );
static int copy_handle_table( struct process *process, struct process *parent );

static const struct object_ops process_ops =
{
    dump_process,
    process_signaled,
    process_satisfied,
    destroy_process
};

/* create a new process */
struct process *create_process(void)
{
    struct process *process;

    if (!(process = malloc( sizeof(*process) ))) return NULL;

    if (!copy_handle_table( process, current ? current->process : NULL ))
    {
        free( process );
        return NULL;
    }
    init_object( &process->obj, &process_ops, NULL );
    process->next            = first_process;
    process->prev            = NULL;
    process->thread_list     = NULL;
    process->exit_code       = 0x103;  /* STILL_ACTIVE */
    process->running_threads = 0;

    if (first_process) first_process->prev = process;
    first_process = process;

    gettimeofday( &process->start_time, NULL );
    /* alloc a handle for the process itself */
    alloc_handle( process, process, PROCESS_ALL_ACCESS, 0 );
    return process;
}

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

    /* we can't have a thread remaining */
    assert( !process->thread_list );
    if (process->next) process->next->prev = process->prev;
    if (process->prev) process->prev->next = process->next;
    else first_process = process->next;
    free_handles( process );
    if (debug_level) memset( process, 0xbb, sizeof(process) );  /* catch errors */
    free( process );
}

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

    printf( "Process next=%p prev=%p\n", process->next, process->prev );
}

static int process_signaled( struct object *obj, struct thread *thread )
{
    struct process *process = (struct process *)obj;
    return (process->running_threads > 0);
}

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

/* get a process from an id (and increment the refcount) */
struct process *get_process_from_id( void *id )
{
    struct process *p = first_process;
    while (p && (p != id)) p = p->next;
    if (p) grab_object( p );
    else SET_ERROR( ERROR_INVALID_PARAMETER );
    return p;
}

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

/* a process has been killed (i.e. its last thread died) */
static void process_killed( struct process *process, int exit_code )
{
    assert( !process->thread_list );
    process->exit_code = exit_code;
    gettimeofday( &process->end_time, NULL );
    wake_up( &process->obj, 0 );
    free_handles( process );
}

/* free the process handle entries */
static void free_handles( struct process *process )
{
    struct handle_entry *entry;
    int handle;

    if (!(entry = process->entries)) return;
    for (handle = 0; handle <= process->handle_last; handle++, entry++)
    {
        struct object *obj = entry->ptr;
        entry->ptr = NULL;
        if (obj) release_object( obj );
    }
    free( process->entries );
    process->handle_count = 0;
    process->handle_last  = -1;
    process->entries = NULL;
}

/* add a thread to a process running threads list */
void add_process_thread( struct process *process, struct thread *thread )
{
    thread->proc_next = process->thread_list;
    thread->proc_prev = NULL;
    if (thread->proc_next) thread->proc_next->proc_prev = thread;
    process->thread_list = thread;
    process->running_threads++;
    grab_object( thread );
}

/* remove a thread from a process running threads list */
void remove_process_thread( struct process *process, struct thread *thread )
{
    assert( process->running_threads > 0 );
    assert( process->thread_list );

    if (thread->proc_next) thread->proc_next->proc_prev = thread->proc_prev;
    if (thread->proc_prev) thread->proc_prev->proc_next = thread->proc_next;
    else process->thread_list = thread->proc_next;

    if (!--process->running_threads)
    {
        /* we have removed the last running thread, exit the process */
        process_killed( process, thread->exit_code );
    }
    release_object( thread );
}

/* grow a handle table */
/* return 1 if OK, 0 on error */
static int grow_handle_table( struct process *process )
{
    struct handle_entry *new_entries;
    int count = process->handle_count;

    if (count >= INT_MAX / 2) return 0;
    count *= 2;
    if (!(new_entries = realloc( process->entries, count * sizeof(struct handle_entry) )))
    {
        SET_ERROR( ERROR_NOT_ENOUGH_MEMORY );
        return 0;
    }
    process->handle_count = count;
    process->entries      = new_entries;
    return 1;
}

/* allocate a handle for an object, incrementing its refcount */
/* return the handle, or -1 on error */
int alloc_handle( struct process *process, void *obj, unsigned int access,
                  int inherit )
{
    struct handle_entry *entry;
    int handle;

    assert( !(access & RESERVED_ALL) );
    if (inherit) access |= RESERVED_INHERIT;

    /* find the first free entry */

    if (!(entry = process->entries)) return -1;
    for (handle = 0; handle <= process->handle_last; handle++, entry++)
        if (!entry->ptr) goto found;

    if (handle >= process->handle_count)
    {
        if (!grow_handle_table( process )) return -1;
        entry = process->entries + handle;  /* the table may have moved */
    }
    process->handle_last = handle;

 found:
    entry->ptr    = grab_object( obj );
    entry->access = access;
    return handle + 1;  /* avoid handle 0 */
}

/* allocate a specific handle for an object, incrementing its refcount */
static int alloc_specific_handle( struct process *process, void *obj, int handle,
                                  unsigned int access, int inherit )
{
    struct handle_entry *entry;
    struct object *old;

    if (handle == -1) return alloc_handle( process, obj, access, inherit );

    assert( !(access & RESERVED_ALL) );
    if (inherit) access |= RESERVED_INHERIT;

    handle--;  /* handles start at 1 */
    if ((handle < 0) || (handle > process->handle_last))
    {
        SET_ERROR( ERROR_INVALID_HANDLE );
        return -1;
    }
    entry = process->entries + handle;

    old = entry->ptr;
    entry->ptr = grab_object( obj );
    entry->access = access;
    if (old) release_object( old );
    return handle + 1;
}

/* return an handle entry, or NULL if the handle is invalid */
static struct handle_entry *get_handle( struct process *process, int handle )
{
    struct handle_entry *entry;

    handle--;  /* handles start at 1 */
    if ((handle < 0) || (handle > process->handle_last)) goto error;
    entry = process->entries + handle;
    if (!entry->ptr) goto error;
    return entry;

 error:
    SET_ERROR( ERROR_INVALID_HANDLE );
    return NULL;
}

/* attempt to shrink a table */
/* return 1 if OK, 0 on error */
static int shrink_handle_table( struct process *process )
{
    struct handle_entry *new_entries;
    struct handle_entry *entry = process->entries + process->handle_last;
    int count = process->handle_count;

    while (process->handle_last >= 0)
    {
        if (entry->ptr) break;
        process->handle_last--;
        entry--;
    }
    if (process->handle_last >= count / 4) return 1;  /* no need to shrink */
    if (count < MIN_HANDLE_ENTRIES * 2) return 1;  /* too small to shrink */
    count /= 2;
    if (!(new_entries = realloc( process->entries,
                                 count * sizeof(struct handle_entry) )))
        return 0;
    process->handle_count = count;
    process->entries      = new_entries;
    return 1;
}

/* copy the handle table of the parent process */
/* return 1 if OK, 0 on error */
static int copy_handle_table( struct process *process, struct process *parent )
{
    struct handle_entry *ptr;
    int i, count, last;

    if (!parent)  /* first process */
    {
        count = MIN_HANDLE_ENTRIES;
        last  = -1;
    }
    else
    {
        assert( parent->entries );
        count = parent->handle_count;
        last  = parent->handle_last;
    }

    if (!(ptr = malloc( count * sizeof(struct handle_entry)))) return 0;
    process->entries      = ptr;
    process->handle_count = count;
    process->handle_last  = last;

    if (last >= 0)
    {
        memcpy( ptr, parent->entries, (last + 1) * sizeof(struct handle_entry) );
        for (i = 0; i <= last; i++, ptr++)
        {
            if (!ptr->ptr) continue;
            if (ptr->access & RESERVED_INHERIT) grab_object( ptr->ptr );
            else ptr->ptr = NULL; /* don't inherit this entry */
        }
    }
    /* attempt to shrink the table */
    shrink_handle_table( process );
    return 1;
}

/* close a handle and decrement the refcount of the associated object */
/* return 1 if OK, 0 on error */
int close_handle( struct process *process, int handle )
{
    struct handle_entry *entry;
    struct object *obj;

    if (!(entry = get_handle( process, handle ))) return 0;
    if (entry->access & RESERVED_CLOSE_PROTECT) return 0;  /* FIXME: error code */
    obj = entry->ptr;
    entry->ptr = NULL;
    if (handle-1 == process->handle_last) shrink_handle_table( process );
    release_object( obj );
    return 1;
}

/* retrieve the object corresponding to a handle, incrementing its refcount */
struct object *get_handle_obj( struct process *process, int handle,
                               unsigned int access, const struct object_ops *ops )
{
    struct handle_entry *entry;
    struct object *obj;

    switch( handle )
    {
    case 0xfffffffe:  /* current thread pseudo-handle */
        obj = &current->obj;
        break;
    case 0x7fffffff:  /* current process pseudo-handle */
        obj = (struct object *)current->process;
        break;
    default:
        if (!(entry = get_handle( process, handle ))) return NULL;
        if ((entry->access & access) != access)
        {
            SET_ERROR( ERROR_ACCESS_DENIED );
            return NULL;
        }
        obj = entry->ptr;
        break;
    }
    if (ops && (obj->ops != ops))
    {
        SET_ERROR( ERROR_INVALID_HANDLE );  /* not the right type */
        return NULL;
    }
    return grab_object( obj );
}

/* get/set the handle reserved flags */
/* return the new flags (or -1 on error) */
int set_handle_info( struct process *process, int handle, int mask, int flags )
{
    struct handle_entry *entry;

    if (!(entry = get_handle( process, handle ))) return -1;
    mask  = (mask << RESERVED_SHIFT) & RESERVED_ALL;
    flags = (flags << RESERVED_SHIFT) & mask;
    entry->access = (entry->access & ~mask) | flags;
    return (entry->access & RESERVED_ALL) >> RESERVED_SHIFT;
}

/* duplicate a handle */
int duplicate_handle( struct process *src, int src_handle, struct process *dst,
                      int dst_handle, unsigned int access, int inherit, int options )
{
    struct handle_entry *entry = get_handle( src, src_handle );
    if (!entry) return -1;

    if (options & DUPLICATE_SAME_ACCESS) access = entry->access;
    access &= ~RESERVED_ALL;
    return alloc_specific_handle( dst, entry->ptr, dst_handle, access, inherit );
}

/* dump a handle table on stdout */
void dump_handles( struct process *process )
{
    struct handle_entry *entry;
    int i;

    if (!process->entries) return;
    entry = process->entries;
    for (i = 0; i <= process->handle_last; i++, entry++)
    {
        if (!entry->ptr) continue;
        printf( "%5d: %p %08x ", i + 1, entry->ptr, entry->access );
        entry->ptr->ops->dump( entry->ptr, 0 );
    }
}

/* kill a process on the spot */
void kill_process( struct process *process, int exit_code )
{
    while (process->thread_list)
        kill_thread( process->thread_list, exit_code );
}

/* get all information about a process */
void get_process_info( struct process *process,
                       struct get_process_info_reply *reply )
{
    reply->pid       = process;
    reply->exit_code = process->exit_code;
}
