Ignore:
Timestamp:
Jun 22, 2001, 9:40:28 PM (24 years ago)
Author:
sandervl
Message:

semaphore update

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/hmsemaphore.cpp

    r6060 r6069  
    1 /* $Id: hmsemaphore.cpp,v 1.5 2001-06-21 21:07:54 sandervl Exp $ */
     1/* $Id: hmsemaphore.cpp,v 1.6 2001-06-22 19:40:28 sandervl Exp $ */
    22
    33/*
     
    88 * TODO: No inheritance when CreateSemaphore is called for existing named event semaphore?
    99 *       (see HMCreateSemaphore in handlemanager.cpp)
    10  * TODO: OpenSemaphore does not work right now! initialcount/maximumcount)
     10 * TODO: OpenSemaphore does not work. (get SEM_INFO pointer)
    1111 * TODO: Name collisions with files & mutex not allowed. Check if this can happen in OS/2
    12  * TODO: Does NOT work for sharing semaphores between processes!!
    1312 *
    1413 * Project Odin Software License can be found in LICENSE.TXT
     
    4443#include <stdlib.h>
    4544#include <string.h>
     45#include <heapshared.h>
    4646#include "unicode.h"
    4747#include "misc.h"
     
    6262#endif
    6363
     64typedef struct {
     65    LONG currentCount;
     66    LONG maximumCount;
     67    LONG refCount;
     68    HEV  hev;
     69} SEM_INFO, *PSEM_INFO;
    6470
    6571/*****************************************************************************
     
    125131  }
    126132  pHMHandleData->dwAccess  = SEMAPHORE_ALL_ACCESS_W;
    127   pHMHandleData->dwFlags   = lMaximumCount;
    128   pHMHandleData->dwCreation= lInitialCount;
    129   pHMHandleData->hHMHandle = hev;
     133  PSEM_INFO pSemInfo       = (PSEM_INFO)_smalloc(sizeof(SEM_INFO));
     134  pSemInfo->refCount       = 1;
     135  pSemInfo->hev            = hev;
     136  pSemInfo->maximumCount   = lMaximumCount;
     137  pSemInfo->currentCount   = lInitialCount;
     138  pHMHandleData->hHMHandle = (DWORD)pSemInfo;
     139  pHMHandleData->dwInternalType = HMTYPE_SEMAPHORE;
    130140  return ERROR_SUCCESS_W;
    131141#else
     
    196206  }
    197207  pHMHandleData->hHMHandle = hev;
     208  pHMHandleData->dwInternalType = HMTYPE_SEMAPHORE;
    198209  return ERROR_SUCCESS_W;
    199210#else
     
    235246{
    236247  APIRET rc;
    237 
    238   if(pHMHandleData->hHMHandle) {
    239       rc = DosCloseEventSem((HEV)pHMHandleData->hHMHandle);
     248  PSEM_INFO pSemInfo  = (PSEM_INFO)pHMHandleData->hHMHandle;
     249
     250  if(pSemInfo) {
     251      rc = DosCloseEventSem(pSemInfo->hev);
    240252      if(rc) {
    241           dprintf(("DosCloseEventSem %x failed with rc %d", pHMHandleData->hHMHandle, rc));
     253          dprintf(("DosCloseEventSem %x failed with rc %d", pSemInfo->hev, rc));
    242254          SetLastError(error2WinError(rc));
    243255          return FALSE;
     256      }
     257      if(InterlockedDecrement(&pSemInfo->refCount) == 0) {
     258          free(pSemInfo);
    244259      }
    245260  }
     
    273288{
    274289  APIRET rc;
    275   HEV hev;
     290  HEV    hev;
     291  PSEM_INFO pSemInfo  = (PSEM_INFO)pHMSrcHandle->hHMHandle;
    276292 
    277293  dprintf(("KERNEL32:HandleManager::DuplicateHandle %s(%08x,%08x,%08x,%08x,%08x)",
     
    285301      return FALSE;
    286302  }
    287   hev = (HEV)pHMSrcHandle->hHMHandle;
    288   rc = DosOpenEventSem(NULL, &hev);
    289   if(rc) {
    290       dprintf(("DosOpenEventSem %x failed with rc %d", pHMSrcHandle->hHMHandle, rc));
    291       pHMHandleData->hHMHandle = 0;
    292       SetLastError(error2WinError(rc));
    293       return FALSE;
    294   }
     303  InterlockedIncrement(&pSemInfo->refCount);
    295304  pHMHandleData->dwAccess  = fdwAccess;
    296   pHMHandleData->dwFlags   = pHMSrcHandle->dwFlags;    //lMaximumCount;
    297   pHMHandleData->dwCreation= pHMSrcHandle->dwCreation; //lInitialCount;
    298   pHMHandleData->hHMHandle = hev;
     305  pHMHandleData->hHMHandle = (DWORD)pSemInfo;
     306  pHMHandleData->dwInternalType = HMTYPE_SEMAPHORE;
    299307  SetLastError(ERROR_SUCCESS_W);
    300308  return TRUE;
     
    317325
    318326DWORD HMDeviceSemaphoreClass::WaitForSingleObject(PHMHANDLEDATA pHMHandleData,
    319                                                DWORD         dwTimeout)
     327                                                  DWORD         dwTimeout)
    320328{
    321329 DWORD rc;
     
    331339  }
    332340
    333   rc = DosWaitEventSem(pHMHandleData->hHMHandle, dwTimeout);
     341  PSEM_INFO pSemInfo  = (PSEM_INFO)pHMHandleData->hHMHandle;
     342
     343  if(InterlockedDecrement(&pSemInfo->currentCount) >= 0) {
     344      SetLastError(ERROR_SUCCESS_W);
     345      return WAIT_OBJECT_0_W; 
     346  }
     347
     348  rc = DosWaitEventSem(pSemInfo->hev, dwTimeout);
    334349  if(rc && rc != ERROR_INTERRUPT && rc != ERROR_TIMEOUT && rc != ERROR_SEM_OWNER_DIED) {
    335       dprintf(("DosWaitEventSem %x failed with rc %d", pHMHandleData->hHMHandle, rc));
     350      dprintf(("DosWaitEventSem %x failed with rc %d", pSemInfo->hev, rc));
    336351      SetLastError(error2WinError(rc));
    337352      return WAIT_FAILED_W;
     
    477492  }
    478493
    479   rc = DosResetEventSem(pHMHandleData->hHMHandle, &count);
     494  PSEM_INFO pSemInfo  = (PSEM_INFO)pHMHandleData->hHMHandle;
     495
     496  if(InterlockedIncrement(&pSemInfo->currentCount) > 0) {
     497      //TODO: this is NOT thread safe:
     498      if(pSemInfo->currentCount > pSemInfo->maximumCount) {
     499          pSemInfo->currentCount = pSemInfo->maximumCount;
     500      }
     501      SetLastError(ERROR_SUCCESS_W);
     502      return TRUE; 
     503  }
     504
     505  rc = DosResetEventSem(pSemInfo->hev, &count);
    480506  if(rc) {
    481       dprintf(("DosResetEventSem %x failed with rc %d", pHMHandleData->hHMHandle, rc));
     507      dprintf(("DosResetEventSem %x failed with rc %d", pSemInfo->hev, rc));
    482508      SetLastError(error2WinError(rc));
    483509      return FALSE;
Note: See TracChangeset for help on using the changeset viewer.