/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* $Id: sslmutex.c,v 1.28 2012/04/25 14:50:12 gerv%gerv.net Exp $ */

#include "seccomon.h"
/* This ifdef should match the one in sslsnce.c */
#if defined(XP_UNIX) || defined(XP_WIN32) || defined (XP_OS2) || defined(XP_BEOS)

#include "sslmutex.h"
#include "prerr.h"

static SECStatus single_process_sslMutex_Init(sslMutex* pMutex)
{
    PR_ASSERT(pMutex != 0 && pMutex->u.sslLock == 0 );
    
    pMutex->u.sslLock = PR_NewLock();
    if (!pMutex->u.sslLock) {
        return SECFailure;
    }
    return SECSuccess;
}

static SECStatus single_process_sslMutex_Destroy(sslMutex* pMutex)
{
    PR_ASSERT(pMutex != 0);
    PR_ASSERT(pMutex->u.sslLock!= 0);
    if (!pMutex->u.sslLock) {
        PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
        return SECFailure;
    }
    PR_DestroyLock(pMutex->u.sslLock);
    return SECSuccess;
}

static SECStatus single_process_sslMutex_Unlock(sslMutex* pMutex)
{
    PR_ASSERT(pMutex != 0 );
    PR_ASSERT(pMutex->u.sslLock !=0);
    if (!pMutex->u.sslLock) {
        PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
        return SECFailure;
    }
    PR_Unlock(pMutex->u.sslLock);
    return SECSuccess;
}

static SECStatus single_process_sslMutex_Lock(sslMutex* pMutex)
{
    PR_ASSERT(pMutex != 0);
    PR_ASSERT(pMutex->u.sslLock != 0 );
    if (!pMutex->u.sslLock) {
        PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
        return SECFailure;
    }
    PR_Lock(pMutex->u.sslLock);
    return SECSuccess;
}

#if defined(LINUX) || defined(AIX) || defined(BEOS) || defined(BSDI) || (defined(NETBSD) && __NetBSD_Version__ < 500000000) || defined(OPENBSD)

#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include "unix_err.h"
#include "pratom.h"

#define SSL_MUTEX_MAGIC 0xfeedfd
#define NONBLOCKING_POSTS 1	/* maybe this is faster */

#if NONBLOCKING_POSTS

#ifndef FNONBLOCK
#define FNONBLOCK O_NONBLOCK
#endif

static int
setNonBlocking(int fd, int nonBlocking)
{
    int flags;
    int err;

    flags = fcntl(fd, F_GETFL, 0);
    if (0 > flags)
	return flags;
    if (nonBlocking)
	flags |= FNONBLOCK;
    else
	flags &= ~FNONBLOCK;
    err = fcntl(fd, F_SETFL, flags);
    return err;
}
#endif

SECStatus
sslMutex_Init(sslMutex *pMutex, int shared)
{
    int  err;
    PR_ASSERT(pMutex);
    pMutex->isMultiProcess = (PRBool)(shared != 0);
    if (!shared) {
        return single_process_sslMutex_Init(pMutex);
    }
    pMutex->u.pipeStr.mPipes[0] = -1;
    pMutex->u.pipeStr.mPipes[1] = -1;
    pMutex->u.pipeStr.mPipes[2] = -1;
    pMutex->u.pipeStr.nWaiters  =  0;

    err = pipe(pMutex->u.pipeStr.mPipes);
    if (err) {
	nss_MD_unix_map_default_error(errno);
	return err;
    }
#if NONBLOCKING_POSTS
    err = setNonBlocking(pMutex->u.pipeStr.mPipes[1], 1);
    if (err)
	goto loser;
#endif

    pMutex->u.pipeStr.mPipes[2] = SSL_MUTEX_MAGIC;

#if defined(LINUX) && defined(i386)
    /* Pipe starts out empty */
    return SECSuccess;
#else
    /* Pipe starts with one byte. */
    return sslMutex_Unlock(pMutex);
#endif

loser:
    nss_MD_unix_map_default_error(errno);
    close(pMutex->u.pipeStr.mPipes[0]);
    close(pMutex->u.pipeStr.mPipes[1]);
    return SECFailure;
}

SECStatus
sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
{
    if (PR_FALSE == pMutex->isMultiProcess) {
        return single_process_sslMutex_Destroy(pMutex);
    }
    if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) {
	PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
	return SECFailure;
    }
    close(pMutex->u.pipeStr.mPipes[0]);
    close(pMutex->u.pipeStr.mPipes[1]);

    if (processLocal) {
	return SECSuccess;
    }

    pMutex->u.pipeStr.mPipes[0] = -1;
    pMutex->u.pipeStr.mPipes[1] = -1;
    pMutex->u.pipeStr.mPipes[2] = -1;
    pMutex->u.pipeStr.nWaiters  =  0;

    return SECSuccess;
}

#if defined(LINUX) && defined(i386)
/* No memory barrier needed for this platform */

/* nWaiters includes the holder of the lock (if any) and the number
** threads waiting for it.  After incrementing nWaiters, if the count
** is exactly 1, then you have the lock and may proceed.  If the 
** count is greater than 1, then you must wait on the pipe.
*/ 


SECStatus 
sslMutex_Unlock(sslMutex *pMutex)
{
    PRInt32 newValue;
    if (PR_FALSE == pMutex->isMultiProcess) {
        return single_process_sslMutex_Unlock(pMutex);
    }

    if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) {
	PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
	return SECFailure;
    }
    /* Do Memory Barrier here. */
    newValue = PR_ATOMIC_DECREMENT(&pMutex->u.pipeStr.nWaiters);
    if (newValue > 0) {
	int  cc;
	char c  = 1;
	do {
	    cc = write(pMutex->u.pipeStr.mPipes[1], &c, 1);
	} while (cc < 0 && (errno == EINTR || errno == EAGAIN));
	if (cc != 1) {
	    if (cc < 0)
		nss_MD_unix_map_default_error(errno);
	    else
		PORT_SetError(PR_UNKNOWN_ERROR);
	    return SECFailure;
	}
    }
    return SECSuccess;
}

SECStatus 
sslMutex_Lock(sslMutex *pMutex)
{
    PRInt32 newValue;
    if (PR_FALSE == pMutex->isMultiProcess) {
        return single_process_sslMutex_Lock(pMutex);
    }

    if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) {
	PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
	return SECFailure;
    }
    newValue = PR_ATOMIC_INCREMENT(&pMutex->u.pipeStr.nWaiters);
    /* Do Memory Barrier here. */
    if (newValue > 1) {
	int   cc;
	char  c;
	do {
	    cc = read(pMutex->u.pipeStr.mPipes[0], &c, 1);
	} while (cc < 0 && errno == EINTR);
	if (cc != 1) {
	    if (cc < 0)
		nss_MD_unix_map_default_error(errno);
	    else
		PORT_SetError(PR_UNKNOWN_ERROR);
	    return SECFailure;
	}
    }
    return SECSuccess;
}

#else

/* Using Atomic operations requires the use of a memory barrier instruction 
** on PowerPC, Sparc, and Alpha.  NSPR's PR_Atomic functions do not perform
** them, and NSPR does not provide a function that does them (e.g. PR_Barrier).
** So, we don't use them on those platforms. 
*/

SECStatus 
sslMutex_Unlock(sslMutex *pMutex)
{
    int  cc;
    char c  = 1;

    if (PR_FALSE == pMutex->isMultiProcess) {
        return single_process_sslMutex_Unlock(pMutex);
    }

    if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) {
	PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
	return SECFailure;
    }
    do {
	cc = write(pMutex->u.pipeStr.mPipes[1], &c, 1);
    } while (cc < 0 && (errno == EINTR || errno == EAGAIN));
    if (cc != 1) {
	if (cc < 0)
	    nss_MD_unix_map_default_error(errno);
	else
	    PORT_SetError(PR_UNKNOWN_ERROR);
	return SECFailure;
    }

    return SECSuccess;
}

SECStatus 
sslMutex_Lock(sslMutex *pMutex)
{
    int   cc;
    char  c;

    if (PR_FALSE == pMutex->isMultiProcess) {
        return single_process_sslMutex_Lock(pMutex);
    }
 
    if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) {
	PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
	return SECFailure;
    }

    do {
	cc = read(pMutex->u.pipeStr.mPipes[0], &c, 1);
    } while (cc < 0 && errno == EINTR);
    if (cc != 1) {
	if (cc < 0)
	    nss_MD_unix_map_default_error(errno);
	else
	    PORT_SetError(PR_UNKNOWN_ERROR);
	return SECFailure;
    }

    return SECSuccess;
}

#endif

#elif defined(WIN32)

#include "win32err.h"

/* on Windows, we need to find the optimal type of locking mechanism to use
 for the sslMutex.

 There are 3 cases :
 1) single-process, use a PRLock, as for all other platforms
 2) Win95 multi-process, use a Win32 mutex
 3) on WINNT multi-process, use a PRLock + a Win32 mutex

*/

#ifdef WINNT

SECStatus sslMutex_2LevelInit(sslMutex *sem)
{
    /*  the following adds a PRLock to sslMutex . This is done in each
        process of a multi-process server and is only needed on WINNT, if
        using fibers. We can't tell if native threads or fibers are used, so
        we always do it on WINNT
    */
    PR_ASSERT(sem);
    if (sem) {
        /* we need to reset the sslLock in the children or the single_process init
           function below will assert */
        sem->u.sslLock = NULL;
    }
    return single_process_sslMutex_Init(sem);
}

static SECStatus sslMutex_2LevelDestroy(sslMutex *sem)
{
    return single_process_sslMutex_Destroy(sem);
}

#endif

SECStatus
sslMutex_Init(sslMutex *pMutex, int shared)
{
#ifdef WINNT
    SECStatus retvalue;
#endif
    HANDLE hMutex;
    SECURITY_ATTRIBUTES attributes =
                                { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };

    PR_ASSERT(pMutex != 0 && (pMutex->u.sslMutx == 0 || 
              pMutex->u.sslMutx == INVALID_HANDLE_VALUE) );
    
    pMutex->isMultiProcess = (PRBool)(shared != 0);
    
    if (PR_FALSE == pMutex->isMultiProcess) {
        return single_process_sslMutex_Init(pMutex);
    }
    
#ifdef WINNT
    /*  we need a lock on WINNT for fibers in the parent process */
    retvalue = sslMutex_2LevelInit(pMutex);
    if (SECSuccess != retvalue)
        return SECFailure;
#endif
    
    if (!pMutex || ((hMutex = pMutex->u.sslMutx) != 0 && 
        hMutex != INVALID_HANDLE_VALUE)) {
        PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
        return SECFailure;
    }
    attributes.bInheritHandle = (shared ? TRUE : FALSE);
    hMutex = CreateMutex(&attributes, FALSE, NULL);
    if (hMutex == NULL) {
        hMutex = INVALID_HANDLE_VALUE;
        nss_MD_win32_map_default_error(GetLastError());
        return SECFailure;
    }
    pMutex->u.sslMutx = hMutex;
    return SECSuccess;
}

SECStatus
sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
{
    HANDLE hMutex;
    int    rv;
    int retvalue = SECSuccess;

    PR_ASSERT(pMutex != 0);
    if (PR_FALSE == pMutex->isMultiProcess) {
        return single_process_sslMutex_Destroy(pMutex);
    }

    /*  multi-process mode */    
#ifdef WINNT
    /* on NT, get rid of the PRLock used for fibers within a process */
    retvalue = sslMutex_2LevelDestroy(pMutex);
#endif
    
    PR_ASSERT( pMutex->u.sslMutx != 0 && 
               pMutex->u.sslMutx != INVALID_HANDLE_VALUE);
    if (!pMutex || (hMutex = pMutex->u.sslMutx) == 0 
        || hMutex == INVALID_HANDLE_VALUE) {
        PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
        return SECFailure;
    }
    
    rv = CloseHandle(hMutex); /* ignore error */
    if (!processLocal && rv) {
        pMutex->u.sslMutx = hMutex = INVALID_HANDLE_VALUE;
    }
    if (!rv) {
        nss_MD_win32_map_default_error(GetLastError());
        retvalue = SECFailure;
    }
    return retvalue;
}

int 
sslMutex_Unlock(sslMutex *pMutex)
{
    BOOL   success = FALSE;
    HANDLE hMutex;

    PR_ASSERT(pMutex != 0 );
    if (PR_FALSE == pMutex->isMultiProcess) {
        return single_process_sslMutex_Unlock(pMutex);
    }
    
    PR_ASSERT(pMutex->u.sslMutx != 0 && 
              pMutex->u.sslMutx != INVALID_HANDLE_VALUE);
    if (!pMutex || (hMutex = pMutex->u.sslMutx) == 0 ||
        hMutex == INVALID_HANDLE_VALUE) {
        PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
        return SECFailure;
    }
    success = ReleaseMutex(hMutex);
    if (!success) {
        nss_MD_win32_map_default_error(GetLastError());
        return SECFailure;
    }
#ifdef WINNT
    return single_process_sslMutex_Unlock(pMutex);
    /* release PRLock for other fibers in the process */
#else
    return SECSuccess;
#endif
}

int 
sslMutex_Lock(sslMutex *pMutex)
{
    HANDLE    hMutex;
    DWORD     event;
    DWORD     lastError;
    SECStatus rv;
    SECStatus retvalue = SECSuccess;
    PR_ASSERT(pMutex != 0);

    if (PR_FALSE == pMutex->isMultiProcess) {
        return single_process_sslMutex_Lock(pMutex);
    }
#ifdef WINNT
    /* lock first to preserve from other threads/fibers
       in the same process */
    retvalue = single_process_sslMutex_Lock(pMutex);
#endif
    PR_ASSERT(pMutex->u.sslMutx != 0 && 
              pMutex->u.sslMutx != INVALID_HANDLE_VALUE);
    if (!pMutex || (hMutex = pMutex->u.sslMutx) == 0 || 
        hMutex == INVALID_HANDLE_VALUE) {
        PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
        return SECFailure;      /* what else ? */
    }
    /* acquire the mutex to be the only owner accross all other processes */
    event = WaitForSingleObject(hMutex, INFINITE);
    switch (event) {
    case WAIT_OBJECT_0:
    case WAIT_ABANDONED:
        rv = SECSuccess;
        break;

    case WAIT_TIMEOUT:
#if defined(WAIT_IO_COMPLETION)
    case WAIT_IO_COMPLETION:
#endif
    default:            /* should never happen. nothing we can do. */
        PR_ASSERT(!("WaitForSingleObject returned invalid value."));
	PORT_SetError(PR_UNKNOWN_ERROR);
	rv = SECFailure;
	break;

    case WAIT_FAILED:           /* failure returns this */
        rv = SECFailure;
        lastError = GetLastError();     /* for debugging */
        nss_MD_win32_map_default_error(lastError);
        break;
    }

    if (! (SECSuccess == retvalue && SECSuccess == rv)) {
        return SECFailure;
    }
    
    return SECSuccess;
}

#elif defined(XP_UNIX)

#include <errno.h>
#include "unix_err.h"

SECStatus 
sslMutex_Init(sslMutex *pMutex, int shared)
{
    int rv;
    PR_ASSERT(pMutex);
    pMutex->isMultiProcess = (PRBool)(shared != 0);
    if (!shared) {
        return single_process_sslMutex_Init(pMutex);
    }
    do {
        rv = sem_init(&pMutex->u.sem, shared, 1);
    } while (rv < 0 && errno == EINTR);
    if (rv < 0) {
        nss_MD_unix_map_default_error(errno);
        return SECFailure;
    }
    return SECSuccess;
}

SECStatus 
sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
{
    int rv;
    if (PR_FALSE == pMutex->isMultiProcess) {
        return single_process_sslMutex_Destroy(pMutex);
    }

    /* semaphores are global resources. See SEM_DESTROY(3) man page */
    if (processLocal) {
	return SECSuccess;
    }
    do {
	rv = sem_destroy(&pMutex->u.sem);
    } while (rv < 0 && errno == EINTR);
    if (rv < 0) {
	nss_MD_unix_map_default_error(errno);
	return SECFailure;
    }
    return SECSuccess;
}

SECStatus 
sslMutex_Unlock(sslMutex *pMutex)
{
    int rv;
    if (PR_FALSE == pMutex->isMultiProcess) {
        return single_process_sslMutex_Unlock(pMutex);
    }
    do {
	rv = sem_post(&pMutex->u.sem);
    } while (rv < 0 && errno == EINTR);
    if (rv < 0) {
	nss_MD_unix_map_default_error(errno);
	return SECFailure;
    }
    return SECSuccess;
}

SECStatus 
sslMutex_Lock(sslMutex *pMutex)
{
    int rv;
    if (PR_FALSE == pMutex->isMultiProcess) {
        return single_process_sslMutex_Lock(pMutex);
    }
    do {
	rv = sem_wait(&pMutex->u.sem);
    } while (rv < 0 && errno == EINTR);
    if (rv < 0) {
	nss_MD_unix_map_default_error(errno);
	return SECFailure;
    }
    return SECSuccess;
}

#else

SECStatus 
sslMutex_Init(sslMutex *pMutex, int shared)
{
    PR_ASSERT(pMutex);
    pMutex->isMultiProcess = (PRBool)(shared != 0);
    if (!shared) {
        return single_process_sslMutex_Init(pMutex);
    }
    PORT_Assert(!("sslMutex_Init not implemented for multi-process applications !"));
    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
    return SECFailure;
}

SECStatus 
sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
{
    PR_ASSERT(pMutex);
    if (PR_FALSE == pMutex->isMultiProcess) {
        return single_process_sslMutex_Destroy(pMutex);
    }
    PORT_Assert(!("sslMutex_Destroy not implemented for multi-process applications !"));
    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
    return SECFailure;
}

SECStatus 
sslMutex_Unlock(sslMutex *pMutex)
{
    PR_ASSERT(pMutex);
    if (PR_FALSE == pMutex->isMultiProcess) {
        return single_process_sslMutex_Unlock(pMutex);
    }
    PORT_Assert(!("sslMutex_Unlock not implemented for multi-process applications !"));
    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
    return SECFailure;
}

SECStatus 
sslMutex_Lock(sslMutex *pMutex)
{
    PR_ASSERT(pMutex);
    if (PR_FALSE == pMutex->isMultiProcess) {
        return single_process_sslMutex_Lock(pMutex);
    }
    PORT_Assert(!("sslMutex_Lock not implemented for multi-process applications !"));
    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
    return SECFailure;
}

#endif

#endif
