summaryrefslogblamecommitdiffstats
path: root/private/os2/server/srvsem.c
blob: e58f0354e54719e9666d60312ff80c3422d7bfb2 (plain) (tree)



































































































































































































































































                                                                                
/*++

Copyright (c) 1989  Microsoft Corporation

Module Name:

    srvsem.c

Abstract:

    Semaphore API

Author:

    Steve Wood (stevewo) 11-Oct-1989

Revision History:

--*/

#define INCL_OS2V20_SEMAPHORES
#define INCL_OS2V20_ERRORS
#include "os2srv.h"

//
// These are dummy variable & dummy routine for the use of two macros
// AcquireHandleTableLock and ReleaseHandleTableLock. In the server,
// these macros should always work, so we set them both to NULL.
//
BOOLEAN  Od2SigHandlingInProgress = (BOOLEAN)NULL;
ULONG Od2ThreadId()
{
    return((ULONG)NULL);
}

NTSTATUS
Os2InitializeSemaphores( VOID )
{
    Os2SharedSemaphoreTable =
        Or2CreateHandleTable( Os2Heap, sizeof( OS2_SEMAPHORE ), 32 );

    if (Os2SharedSemaphoreTable == NULL) {
        return( STATUS_NO_MEMORY );
        }
    else {
        return( STATUS_SUCCESS );
        }
}

BOOLEAN
Os2SemaphoreCreateProcedure(
    IN POS2_SEMAPHORE Semaphore,
    IN POS2_SEMAPHORE NewSemaphore
    )
{
    if (Semaphore->Name.Length != 0) {
        if (RtlEqualString( &Semaphore->Name, &NewSemaphore->Name, FALSE )) {
            return( TRUE );
            }
        }

    return( FALSE );
}

BOOLEAN
Os2SemaphoreOpenProcedure(
    IN POS2_SEMAPHORE Semaphore,
    IN POS2_SEMAPHORE OpenSemaphore
    )
{
    if (Semaphore->Name.Length != 0) {
        if (RtlEqualString( &Semaphore->Name, &OpenSemaphore->Name, FALSE )) {
            return( TRUE );
            }
        }
    return( FALSE );
}


APIRET
Os2ProcessSemaphoreName(
    IN PSTRING ObjectName,
    IN POS2_SEMAPHORE Semaphore OPTIONAL,
    OUT PULONG ExistingHandleIndex OPTIONAL
    )
{
    OS2_SEMAPHORE ExistingSemaphore;
    PSZ src, dst;
    USHORT n;
    APIRET rc;

    AcquireHandleTableLock( Os2SharedSemaphoreTable );

    if (ARGUMENT_PRESENT( ExistingHandleIndex )) {
        Semaphore = &ExistingSemaphore;
        }

    rc = NO_ERROR;
    if ((n = ObjectName->Length) == 0) {
        Semaphore->Name.Length = 0;
        Semaphore->Name.MaximumLength = 0;
        Semaphore->Name.Buffer = NULL;
        }
    else {
        dst = RtlAllocateHeap( Os2Heap, 0, n );
        if (dst == NULL) {
            rc = ERROR_NOT_ENOUGH_MEMORY;
            }
        else {
            src = ObjectName->Buffer;
            Semaphore->Name.Length = n;
            Semaphore->Name.MaximumLength = n;
            Semaphore->Name.Buffer = dst;
            while (n--) {
                *dst++ = *src++;
                }

            if (Or2EnumHandleTable(
                    Os2SharedSemaphoreTable,
                    (OR2_ENUMERATE_HANDLE_ROUTINE)
                        (ARGUMENT_PRESENT( ExistingHandleIndex ) ?
                            Os2SemaphoreOpenProcedure :
                            Os2SemaphoreCreateProcedure),
                    (PVOID)Semaphore,
                    ExistingHandleIndex
                    )
               ) {
                if (!ARGUMENT_PRESENT( ExistingHandleIndex )) {
                    rc = ERROR_DUPLICATE_NAME;
                    }
                }
            else {
                if (ARGUMENT_PRESENT( ExistingHandleIndex )) {
                    rc = ERROR_SEM_NOT_FOUND;
                    }
                }

            if (ARGUMENT_PRESENT( ExistingHandleIndex ) || rc != NO_ERROR) {
                RtlFreeHeap( Os2Heap, 0,
                             Semaphore->Name.Buffer
                           );
                }
            }
        }

    return( rc );
}


PVOID
Os2DestroySemaphore(
    IN POS2_SEMAPHORE Semaphore,
    IN ULONG HandleIndex
    )
{
    PVOID Value;

    Value = Semaphore->u.Value;

    if (Semaphore->Name.Length != 0) {
        RtlFreeHeap( Os2Heap, 0,
                     Semaphore->Name.Buffer
                   );
        }

    Or2DestroyHandle( Os2SharedSemaphoreTable,
                               HandleIndex
                             );

    return( Value );
}


POS2_SEMAPHORE
Os2ReferenceSemaphore(
    IN POS2_SEMAPHORE Semaphore
    )
{
    Semaphore->PointerCount++;

    return( Semaphore );
}


VOID
Os2DereferenceSemaphore(
    IN POS2_SEMAPHORE Semaphore
    )
{
    Semaphore->PointerCount--;

    return;
}


VOID
Os2ThreadWaitingOnSemaphore(
    IN POS2_THREAD t,
    IN POS2_SEMAPHORE Semaphore,
    IN BOOLEAN AboutToWait
    )
{
    if (AboutToWait) {
        t->WaitingForSemaphore = Os2ReferenceSemaphore( Semaphore );
        ReleaseHandleTableLock( Os2SharedSemaphoreTable );
        }
    else {
        AcquireHandleTableLock( Os2SharedSemaphoreTable );
        t->WaitingForSemaphore = NULL;
        Os2DereferenceSemaphore( Semaphore );
        ReleaseHandleTableLock( Os2SharedSemaphoreTable );
        }
}


#if DBG

VOID
Os2SemaphoreDumpProcedure(
    IN POS2_SEMAPHORE Semaphore,
    IN ULONG HandleIndex,
    IN PVOID DumpParameter
    )
{
    UNREFERENCED_PARAMETER(DumpParameter);
    DbgPrint( " %3ld   %2ld  %4ld %4ld %8lx    %.*s\n",
              HandleIndex,
              (ULONG)Semaphore->Type,
              (ULONG)Semaphore->OpenCount,
              (ULONG)Semaphore->PointerCount,
              (ULONG)Semaphore->u.Value,
              Semaphore->Name.Length,
              Semaphore->Name.Buffer
            );
    return;
}

VOID
Os2DumpSemaphoreTable(
    IN PCHAR Title
    )
{
    ULONG n;

    if (Os2SharedSemaphoreTable->CountEntries >
        Os2SharedSemaphoreTable->CountFreeEntries
       ) {
        DbgPrint( "\nDump Of OS/2 Server Shared Semaphore Table: %s\n", Title );
        DbgPrint( "Index Type Ocnt Pcnt   Value   Name\n" );
        n = Or2DumpHandleTable(
                Os2SharedSemaphoreTable,
                (OR2_DUMP_HANDLE_ROUTINE)Os2SemaphoreDumpProcedure,
                NULL
                );

        DbgPrint( "Total number of valid shared semaphores: %ld\n", n );
        }
}

#endif // DBG