/*
 * Win32 mutexes
 *
 * Copyright 1998 Alexandre Julliard
 */

#include <assert.h>
#include "windows.h"
#include "winerror.h"
#include "k32obj.h"
#include "process.h"
#include "thread.h"
#include "heap.h"
#include "server/request.h"
#include "server.h"

typedef struct _MUTEX
{
    K32OBJ         header;
    THREAD_QUEUE   wait_queue;
    DWORD          owner;
    DWORD          count;
    BOOL32         abandoned;
    struct _MUTEX *next;
    struct _MUTEX *prev;
} MUTEX;

static BOOL32 MUTEX_Signaled( K32OBJ *obj, DWORD thread_id );
static BOOL32 MUTEX_Satisfied( K32OBJ *obj, DWORD thread_id );
static void MUTEX_AddWait( K32OBJ *obj, DWORD thread_id );
static void MUTEX_RemoveWait( K32OBJ *obj, DWORD thread_id );
static void MUTEX_Destroy( K32OBJ *obj );

const K32OBJ_OPS MUTEX_Ops =
{
    MUTEX_Signaled,    /* signaled */
    MUTEX_Satisfied,   /* satisfied */
    MUTEX_AddWait,     /* add_wait */
    MUTEX_RemoveWait,  /* remove_wait */
    NULL,              /* read */
    NULL,              /* write */
    MUTEX_Destroy      /* destroy */
};


/***********************************************************************
 *           MUTEX_Release
 *
 * Release a mutex once the count is 0.
 * Helper function for MUTEX_Abandon and ReleaseMutex.
 */
static void MUTEX_Release( MUTEX *mutex )
{
    /* Remove the mutex from the thread list of owned mutexes */
    if (mutex->next) mutex->next->prev = mutex->prev;
    if (mutex->prev) mutex->prev->next = mutex->next;
    else THREAD_Current()->mutex_list = &mutex->next->header;
    mutex->next = mutex->prev = NULL;
    mutex->owner = 0;
    SYNC_WakeUp( &mutex->wait_queue, INFINITE32 );
}


/***********************************************************************
 *           MUTEX_Abandon
 *
 * Abandon a mutex.
 */
void MUTEX_Abandon( K32OBJ *obj )
{
    MUTEX *mutex = (MUTEX *)obj;
    assert( obj->type == K32OBJ_MUTEX );
    assert( mutex->count && (mutex->owner == GetCurrentThreadId()) );
    mutex->count = 0;
    mutex->abandoned = TRUE;
    MUTEX_Release( mutex );
}


/***********************************************************************
 *           CreateMutex32A   (KERNEL32.166)
 */
HANDLE32 WINAPI CreateMutex32A( SECURITY_ATTRIBUTES *sa, BOOL32 owner,
                                LPCSTR name )
{
    struct create_mutex_request req;
    struct create_mutex_reply reply;
    int len = name ? strlen(name) + 1 : 0;
    HANDLE32 handle;
    MUTEX *mutex;

    req.owned   = owner;
    req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);

    CLIENT_SendRequest( REQ_CREATE_MUTEX, -1, 2, &req, sizeof(req), name, len );
    CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) );
    CHECK_LEN( len, sizeof(reply) );
    if (reply.handle == -1) return NULL;

    SYSTEM_LOCK();
    mutex = (MUTEX *)K32OBJ_Create( K32OBJ_MUTEX, sizeof(*mutex),
                                    name, reply.handle, MUTEX_ALL_ACCESS,
                                    sa, &handle );
    if (mutex)
    {
        /* Finish initializing it */
        mutex->wait_queue = NULL;
        mutex->abandoned  = FALSE;
        mutex->prev       = NULL;
        if (owner)
        {
            K32OBJ **list;
            mutex->owner = GetCurrentThreadId();
            mutex->count = 1;
            /* Add the mutex in the thread list of owned mutexes */
            list = &THREAD_Current()->mutex_list;
            if ((mutex->next = (MUTEX *)*list)) mutex->next->prev = mutex;
            *list = &mutex->header;
        }
        else
        {
            mutex->owner = 0;
            mutex->count = 0;
            mutex->next  = NULL;
        }
        K32OBJ_DecCount( &mutex->header );
    }
    SetLastError(0); /* FIXME */
    SYSTEM_UNLOCK();
    return handle;
}


/***********************************************************************
 *           CreateMutex32W   (KERNEL32.167)
 */
HANDLE32 WINAPI CreateMutex32W( SECURITY_ATTRIBUTES *sa, BOOL32 owner,
                                LPCWSTR name )
{
    LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
    HANDLE32 ret = CreateMutex32A( sa, owner, nameA );
    if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
    return ret;
}


/***********************************************************************
 *           OpenMutex32A   (KERNEL32.541)
 */
HANDLE32 WINAPI OpenMutex32A( DWORD access, BOOL32 inherit, LPCSTR name )
{
    HANDLE32 handle = 0;
    K32OBJ *obj;
    SYSTEM_LOCK();
    if ((obj = K32OBJ_FindNameType( name, K32OBJ_MUTEX )) != NULL)
    {
        handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, -1 );
        K32OBJ_DecCount( obj );
    }
    SYSTEM_UNLOCK();
    return handle;
}


/***********************************************************************
 *           OpenMutex32W   (KERNEL32.542)
 */
HANDLE32 WINAPI OpenMutex32W( DWORD access, BOOL32 inherit, LPCWSTR name )
{
    LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
    HANDLE32 ret = OpenMutex32A( access, inherit, nameA );
    if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
    return ret;
}


/***********************************************************************
 *           ReleaseMutex   (KERNEL32.582)
 */
BOOL32 WINAPI ReleaseMutex( HANDLE32 handle )
{
    struct release_mutex_request req;
    MUTEX *mutex;
    SYSTEM_LOCK();
    if (!(mutex = (MUTEX *)HANDLE_GetObjPtr(PROCESS_Current(), handle,
                                            K32OBJ_MUTEX, MUTEX_MODIFY_STATE,
                                            &req.handle )))
    {
        SYSTEM_UNLOCK();
        return FALSE;
    }
    if (req.handle != -1)
    {
        SYSTEM_UNLOCK();
        CLIENT_SendRequest( REQ_RELEASE_MUTEX, -1, 1, &req, sizeof(req) );
        return !CLIENT_WaitReply( NULL, NULL, 0 );
    }
    if (!mutex->count || (mutex->owner != GetCurrentThreadId()))
    {
        SYSTEM_UNLOCK();
        SetLastError( ERROR_NOT_OWNER );
        return FALSE;
    }
    if (!--mutex->count) MUTEX_Release( mutex );
    K32OBJ_DecCount( &mutex->header );
    SYSTEM_UNLOCK();
    return TRUE;
}


/***********************************************************************
 *           MUTEX_Signaled
 */
static BOOL32 MUTEX_Signaled( K32OBJ *obj, DWORD thread_id )
{
    MUTEX *mutex = (MUTEX *)obj;
    assert( obj->type == K32OBJ_MUTEX );
    return (!mutex->count || (mutex->owner == thread_id));
}


/***********************************************************************
 *           MUTEX_Satisfied
 *
 * Wait on this object has been satisfied.
 */
static BOOL32 MUTEX_Satisfied( K32OBJ *obj, DWORD thread_id )
{
    BOOL32 ret;
    MUTEX *mutex = (MUTEX *)obj;
    assert( obj->type == K32OBJ_MUTEX );
    assert( !mutex->count || (mutex->owner == thread_id) );
    mutex->owner = thread_id;
    if (!mutex->count++)
    {
        /* Add the mutex in the thread list of owned mutexes */
        K32OBJ **list = &THREAD_ID_TO_THDB( thread_id )->mutex_list;
        assert( !mutex->next );
        if ((mutex->next = (MUTEX *)*list)) mutex->next->prev = mutex;
        *list = &mutex->header;
        mutex->prev = NULL;
    }
    ret = mutex->abandoned;
    mutex->abandoned = FALSE;
    return ret;
}


/***********************************************************************
 *           MUTEX_AddWait
 *
 * Add a thread to the object wait queue.
 */
static void MUTEX_AddWait( K32OBJ *obj, DWORD thread_id )
{
    MUTEX *mutex = (MUTEX *)obj;
    assert( obj->type == K32OBJ_MUTEX );
    THREAD_AddQueue( &mutex->wait_queue, THREAD_ID_TO_THDB(thread_id) );
}


/***********************************************************************
 *           MUTEX_RemoveWait
 *
 * Remove a thread from the object wait queue.
 */
static void MUTEX_RemoveWait( K32OBJ *obj, DWORD thread_id )
{
    MUTEX *mutex = (MUTEX *)obj;
    assert( obj->type == K32OBJ_MUTEX );
    THREAD_RemoveQueue( &mutex->wait_queue, THREAD_ID_TO_THDB(thread_id) );
}


/***********************************************************************
 *           MUTEX_Destroy
 */
static void MUTEX_Destroy( K32OBJ *obj )
{
    MUTEX *mutex = (MUTEX *)obj;
    assert( obj->type == K32OBJ_MUTEX );
    /* There cannot be any thread on the list since the ref count is 0 */
    assert( mutex->wait_queue == NULL );
    obj->type = K32OBJ_UNKNOWN;
    HeapFree( SystemHeap, 0, mutex );
}
