Ignore:
Timestamp:
Feb 4, 2003, 12:29:03 PM (23 years ago)
Author:
sandervl
Message:

Support DuplicateHandle for threads; cleaned up semaphore code

File:
1 edited

Legend:

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

    r6086 r9748  
    1 /* $Id: hmsemaphore.cpp,v 1.9 2001-06-23 19:43:50 sandervl Exp $ */
     1/* $Id: hmsemaphore.cpp,v 1.10 2003-02-04 11:29:00 sandervl Exp $ */
    22
    33/*
     
    1010 * 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 *
     13 * TODO: Use DosQueryEventSem to test the posted count against maximum count!!
    1214 *
    1315 * Project Odin Software License can be found in LICENSE.TXT
     
    3133 *****************************************************************************/
    3234
    33 #ifdef USE_OS2SEMAPHORES
    34 #define INCL_DOSSEMAPHORES
    35 #define INCL_DOSERRORS
    36 #define INCL_WIN
    37 #include <os2wrap.h>
    38 #include <win32type.h>
    39 #include <win32api.h>
    40 #include <winconst.h>
    41 #else
    4235#include <os2win.h>
    43 #endif
    4436#include <stdlib.h>
    4537#include <string.h>
     
    5446#define DBG_LOCALLOG    DBG_hmsemaphore
    5547#include "dbglocal.h"
    56 
    57 #ifndef DCE_AUTORESET
    58 #define DCE_AUTORESET   0x1000  /* DosCreateEventSem option to auto-reset  */
    59                                 /* event semaphore on post.                */
    60 #define DCE_POSTONE     0x0800  /* DosCreateEventSem option to post only   */
    61                                 /* waiter and auto-reset the semaphore when*/
    62                                 /* there are multiple waiters.             */
    63 
    64 #endif
    6548
    6649/*****************************************************************************
     
    9578                                              LPCTSTR               lpszSemaphoreName)
    9679{
    97 #ifdef USE_OS2SEMAPHORES
    98   APIRET rc;
    99   HEV hev;
    100   char szSemName[CCHMAXPATH];
    101 
    102 
    103   dprintf(("KERNEL32: HandleManager::Semaphore::CreateSemaphore(%08xh,%08xh,%08xh,%08xh,%s)\n",
    104            pHMHandleData,
    105            lpsa,
    106            lInitialCount,
    107            lMaximumCount,
    108            lpszSemaphoreName));
    109 
    110   if(lMaximumCount <= 0 || lInitialCount < 0 || lInitialCount > lMaximumCount) {
    111       dprintf(("ERROR: invalid parameter"));
    112       return ERROR_INVALID_PARAMETER_W;
    113   }
    114  
    115   if(lpszSemaphoreName) {
    116       strcpy(szSemName, "\\SEM32\\");
    117       strcat(szSemName, lpszSemaphoreName);
    118       lpszSemaphoreName = szSemName;
    119       FixSemName((char *)lpszSemaphoreName);
    120   }
    121   rc = DosCreateEventSem(lpszSemaphoreName, &hev, DCE_POSTONE, lInitialCount);
    122 
    123   if(rc) {
    124       dprintf(("DosCreateEventSem %x failed with rc %d", pHMHandleData->hHMHandle, rc));
    125       pHMHandleData->hHMHandle = 0;
    126       return error2WinError(rc);
    127   }
    128   pHMHandleData->dwAccess  = SEMAPHORE_ALL_ACCESS_W;
    129   PSEM_INFO pSemInfo       = (PSEM_INFO)_smalloc(sizeof(SEM_INFO));
    130   pSemInfo->refCount       = 1;
    131   pSemInfo->hev            = hev;
    132   pSemInfo->maximumCount   = lMaximumCount;
    133   pSemInfo->currentCount   = lInitialCount;
    134   pHMHandleData->hHMHandle = (DWORD)pSemInfo;
    135   pHMHandleData->dwInternalType = HMTYPE_SEMAPHORE;
    136   return ERROR_SUCCESS_W;
    137 #else
    13880  HANDLE hOpen32;
    13981
     
    15698  }
    15799  else
    158     return (O32_GetLastError());
    159 #endif
     100    return (GetLastError());
    160101}
    161102
     
    177118                                            LPCTSTR               lpszSemaphoreName)
    178119{
    179 #ifdef USE_OS2SEMAPHORES
    180   HEV    hev;
    181   APIRET rc;
    182   char szSemName[CCHMAXPATH];
    183 
    184   //TODO: NOT WORKING (initialcount/maximumcount)
    185   dprintf(("KERNEL32: HandleManager::Semaphore::OpenSemaphore(%08xh,%08xh,%s)\n",
    186            pHMHandleData,
    187            fInheritHandle,
    188            lpszSemaphoreName));
    189 
    190   if(lpszSemaphoreName == NULL) {
    191       pHMHandleData->hHMHandle = 0;
    192       return ERROR_INVALID_PARAMETER_W;
    193   }
    194 
    195   strcpy(szSemName, "\\SEM32\\");
    196   strcat(szSemName, lpszSemaphoreName);
    197   FixSemName(szSemName);
    198   rc = DosOpenEventSem(szSemName, &hev);
    199   if(rc) {
    200       dprintf(("DosOpenEventSem %x failed with rc %d", pHMHandleData->hHMHandle, rc));
    201       pHMHandleData->hHMHandle = 0;
    202       return error2WinError(rc);
    203   }
    204   pHMHandleData->hHMHandle = hev;
    205   pHMHandleData->dwInternalType = HMTYPE_SEMAPHORE;
    206   return ERROR_SUCCESS_W;
    207 #else
    208120  HANDLE hOpen32;
    209121
     
    223135  }
    224136  else
    225     return (O32_GetLastError());
    226 #endif
     137    return (GetLastError());
    227138}
    228139
    229 /*****************************************************************************
    230  * Name      : HMDeviceEventClass::CloseHandle
    231  * Purpose   : close the handle
    232  * Parameters: PHMHANDLEDATA pHMHandleData
    233  * Variables :
    234  * Result    : API returncode
    235  * Remark    :
    236  * Status    :
    237  *
    238  * Author    :
    239  *****************************************************************************/
    240 
    241 #ifdef USE_OS2SEMAPHORES
    242 BOOL HMDeviceSemaphoreClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
    243 {
    244   APIRET rc;
    245   PSEM_INFO pSemInfo  = (PSEM_INFO)pHMHandleData->hHMHandle;
    246 
    247   if(pSemInfo) {
    248       rc = DosCloseEventSem(pSemInfo->hev);
    249       if(rc) {
    250           dprintf(("DosCloseEventSem %x failed with rc %d", pSemInfo->hev, rc));
    251           SetLastError(error2WinError(rc));
    252           return FALSE;
    253       }
    254       if(InterlockedDecrement(&pSemInfo->refCount) == 0) {
    255           free(pSemInfo);
    256       }
    257   }
    258   return TRUE;
    259 }
    260 #endif
    261 
    262 
    263 /*****************************************************************************
    264  * Name      : HMDeviceEventClass::DuplicateHandle
    265  * Purpose   :
    266  * Parameters:
    267  *             various parameters as required
    268  * Variables :
    269  * Result    :
    270  * Remark    : the standard behaviour is to return an error code for non-
    271  *             existant request codes
    272  * Status    :
    273  *
    274  * Author    :
    275  *****************************************************************************/
    276 #ifdef USE_OS2SEMAPHORES
    277 BOOL HMDeviceSemaphoreClass::DuplicateHandle(PHMHANDLEDATA pHMHandleData, HANDLE  srcprocess,
    278                                PHMHANDLEDATA pHMSrcHandle,
    279                                HANDLE  destprocess,
    280                                PHANDLE desthandle,
    281                                DWORD   fdwAccess,
    282                                BOOL    fInherit,
    283                                DWORD   fdwOptions,
    284                                DWORD   fdwOdinOptions)
    285 {
    286   APIRET rc;
    287   HEV    hev;
    288   PSEM_INFO pSemInfo  = (PSEM_INFO)pHMSrcHandle->hHMHandle;
    289  
    290   dprintf(("KERNEL32:HandleManager::DuplicateHandle %s(%08x,%08x,%08x,%08x,%08x)",
    291            lpHMDeviceName,
    292            pHMHandleData,
    293            srcprocess, pHMSrcHandle, destprocess, desthandle));
    294 
    295   if(srcprocess != destprocess) {
    296       DebugInt3();
    297       SetLastError(ERROR_ACCESS_DENIED_W);
    298       return FALSE;
    299   }
    300   InterlockedIncrement(&pSemInfo->refCount);
    301   pHMHandleData->dwAccess  = fdwAccess;
    302   pHMHandleData->hHMHandle = (DWORD)pSemInfo;
    303   pHMHandleData->dwInternalType = HMTYPE_SEMAPHORE;
    304   SetLastError(ERROR_SUCCESS_W);
    305   return TRUE;
    306 }
    307 #endif
    308 
    309 #ifdef USE_OS2SEMAPHORES
    310 /*****************************************************************************
    311  * Name      : DWORD HMDeviceSemaphoreClass::WaitForSingleObject
    312  * Purpose   : object synchronization
    313  * Parameters: PHMHANDLEDATA pHMHandleData
    314  *             DWORD dwTimeout
    315  * Variables :
    316  * Result    : API returncode
    317  * Remark    :
    318  * Status    :
    319  *
    320  * Author    : SvL
    321  *****************************************************************************/
    322 
    323 DWORD HMDeviceSemaphoreClass::WaitForSingleObject(PHMHANDLEDATA pHMHandleData,
    324                                                   DWORD         dwTimeout)
    325 {
    326  DWORD rc;
    327 
    328   dprintf2(("KERNEL32: HMDeviceSemaphoreClass::WaitForSingleObject(%08xh %08xh)",
    329             pHMHandleData->hHMHandle, dwTimeout));
    330 
    331   if(!(pHMHandleData->dwAccess & SYNCHRONIZE_W) )
    332   {
    333       dprintf(("ERROR: Access denied!!"));
    334       SetLastError(ERROR_ACCESS_DENIED_W);
    335       return WAIT_FAILED_W;
    336   }
    337 
    338   PSEM_INFO pSemInfo  = (PSEM_INFO)pHMHandleData->hHMHandle;
    339 
    340   if(InterlockedDecrement(&pSemInfo->currentCount) >= 0) {
    341       SetLastError(ERROR_SUCCESS_W);
    342       return WAIT_OBJECT_0_W; 
    343   }
    344 
    345   rc = DosWaitEventSem(pSemInfo->hev, dwTimeout);
    346   if(rc && rc != ERROR_INTERRUPT && rc != ERROR_TIMEOUT && rc != ERROR_SEM_OWNER_DIED) {
    347       dprintf(("DosWaitEventSem %x failed with rc %d", pSemInfo->hev, rc));
    348       SetLastError(error2WinError(rc));
    349       return WAIT_FAILED_W;
    350   }
    351   SetLastError(ERROR_SUCCESS_W);
    352   if(rc == ERROR_INTERRUPT || rc == ERROR_SEM_OWNER_DIED) {
    353       return WAIT_ABANDONED_W;
    354   }
    355   else
    356   if(rc == ERROR_TIMEOUT) {
    357       return WAIT_TIMEOUT_W;
    358   }
    359   return WAIT_OBJECT_0_W;
    360 }
    361 #endif
    362 
    363 #ifdef USE_OS2SEMAPHORES
    364 /*****************************************************************************
    365  * Name      : DWORD HMDeviceSemaphoreClass::WaitForSingleObjectEx
    366  * Purpose   : object synchronization
    367  * Parameters: PHMHANDLEDATA pHMHandleData
    368  *             DWORD dwTimeout
    369  *             BOOL  fAlertable
    370  * Variables :
    371  * Result    : API returncode
    372  * Remark    :
    373  * Status    :
    374  *
    375  * Author    : SvL
    376  *****************************************************************************/
    377 
    378 DWORD HMDeviceSemaphoreClass::WaitForSingleObjectEx(PHMHANDLEDATA pHMHandleData,
    379                                                  DWORD         dwTimeout,
    380                                                  BOOL          fAlertable)
    381 {
    382     dprintf2(("KERNEL32: HMDeviceSemaphoreClass::WaitForSingleObjectEx(%08xh,%08h,%08xh) not implemented correctly.\n",
    383               pHMHandleData->hHMHandle, dwTimeout, fAlertable));
    384 
    385     if(!(pHMHandleData->dwAccess & SYNCHRONIZE_W) )
    386     {
    387         dprintf(("ERROR: Access denied!!"));
    388         SetLastError(ERROR_ACCESS_DENIED_W);
    389         return WAIT_FAILED_W;
    390     }
    391 
    392     return WaitForSingleObject(pHMHandleData, dwTimeout);
    393 }
    394 #endif
    395 
    396 #ifdef USE_OS2SEMAPHORES
    397 /*****************************************************************************
    398  * Name      : BOOL HMDeviceSemaphoreClass::MsgWaitForMultipleObjects
    399  * Purpose   :
    400  * Variables :
    401  * Result    :
    402  * Remark    :
    403  * Status    :
    404  *
    405  * Author    : SvL
    406  *****************************************************************************/
    407 DWORD HMDeviceSemaphoreClass::MsgWaitForMultipleObjects(PHMHANDLEDATA pHMHandleData,
    408                                                         DWORD      nCount,
    409                                                         PHANDLE    pHandles,
    410                                                         BOOL       fWaitAll,
    411                                                         DWORD      dwMilliseconds,
    412                                                         DWORD      dwWakeMask)
    413 {
    414     return HMSemMsgWaitForMultipleObjects(nCount, pHandles, fWaitAll, dwMilliseconds, dwWakeMask);
    415 }
    416 
    417 DWORD HMSemMsgWaitForMultipleObjects(DWORD   cObjects,
    418                                      PHANDLE lphObjects,
    419                                      BOOL    fWaitAll,
    420                                      DWORD   dwTimeout,
    421                                      DWORD   dwWakeMask)
    422 {
    423     PHMHANDLEDATA *pHandles;
    424     HMUX hmux;
    425     PSEMRECORD pSemRec;
    426     int i, j;
    427     APIRET rc;
    428     ULONG  ulUser;
    429     static HMODULE hUser32 = 0;
    430     static BOOL (* WINAPI pfnPeekMessageA)(LPMSG,HWND,UINT,UINT,UINT);
    431 
    432     dprintf(("KERNEL32: WaitForMultipleObjects %d %x %d %x",
    433               cObjects, lphObjects, fWaitAll, dwTimeout));
    434 
    435     if(pfnPeekMessageA == NULL) {
    436           hUser32 = LoadLibraryA("USER32.DLL");
    437           *(FARPROC *)&pfnPeekMessageA = GetProcAddress(hUser32,"PeekMessageA");
    438     }   
    439 
    440     if(cObjects == 1) {
    441         //Can't use DosCreateMuxWaitSem here (will return error 292)
    442         PHMHANDLEDATA pHandle = HMQueryHandleData(lphObjects[0]);
    443         if(pHandle == NULL) {
    444             return WAIT_FAILED_W;
    445         }
    446         if(!(pHandle->dwAccess & SYNCHRONIZE_W) )
    447         {
    448             dprintf(("ERROR: Access denied (handle %x, index 0)!!", lphObjects[0]));
    449             SetLastError(ERROR_ACCESS_DENIED_W);
    450             return WAIT_FAILED_W;
    451         }
    452 
    453         switch(pHandle->dwInternalType) {
    454         case HMTYPE_SEMAPHORE:
    455         {
    456             PSEM_INFO pSemInfo  = (PSEM_INFO)pHandle->hHMHandle;
    457 
    458             dprintf(("KERNEL32: HMWaitForMultipleObjects(S): handle 0: ODIN-%08xh, OS/2-%08xh",
    459                      lphObjects[0], pSemInfo->hev));
    460             if(InterlockedDecrement(&pSemInfo->currentCount) >= 0) {
    461                 return WAIT_OBJECT_0_W;
    462             }
    463             rc = WinWaitEventSem(pSemInfo->hev, dwTimeout);
    464             break;
    465         }
    466         case HMTYPE_EVENTSEM:
    467             dprintf(("KERNEL32: HMWaitForMultipleObjects(E): handle 0: ODIN-%08xh, OS/2-%08xh",
    468                      lphObjects[0], pHandle->hHMHandle));
    469             rc = WinWaitEventSem((HEV)pHandle->hHMHandle, dwTimeout);
    470             break;
    471         case HMTYPE_MUTEXSEM:
    472             dprintf(("KERNEL32: HMWaitForMultipleObjects(M): handle 0: ODIN-%08xh, OS/2-%08xh",
    473                      lphObjects[0], pHandle->hHMHandle));
    474             rc = WinRequestMutexSem((HMTX)pHandle->hHMHandle, dwTimeout);
    475             break;
    476         }
    477         if(rc && rc != ERROR_INTERRUPT && rc != ERROR_TIMEOUT && rc != ERROR_SEM_OWNER_DIED) {
    478             dprintf(("WinWaitEventSem/WinRequestMutexSem %x failed with rc %d", pHandle->hHMHandle, rc));
    479             SetLastError(error2WinError(rc));
    480             return WAIT_FAILED_W;
    481         }
    482         SetLastError(ERROR_SUCCESS_W);
    483         if(rc == ERROR_INTERRUPT || rc == ERROR_SEM_OWNER_DIED) {
    484             dprintf(("WAIT_ABANDONED_W (rc %d)", rc));
    485             return WAIT_ABANDONED_W;
    486         }
    487         else
    488         if(rc == ERROR_TIMEOUT) {
    489             dprintf(("WAIT_TIMEOUT_W (rc %d)", rc));
    490             return WAIT_TIMEOUT_W;
    491         }
    492         MSG msg ;
    493    
    494         if(pfnPeekMessageA(&msg, NULL, 0, 0, PM_NOREMOVE_W) == TRUE) {
    495             dprintf(("WAIT_OBJECT_0_W+1 (rc %d)", rc));
    496             return WAIT_OBJECT_0_W + 1;
    497         }
    498         dprintf(("WAIT_OBJECT_0_W+1 (rc %d)", rc));
    499         return WAIT_OBJECT_0_W;
    500     }
    501     pHandles = (PHMHANDLEDATA *)alloca(cObjects * sizeof(PHMHANDLEDATA));
    502     pSemRec  = (PSEMRECORD)alloca(cObjects * sizeof(SEMRECORD));
    503     if(pHandles == NULL || pSemRec == NULL) {
    504         dprintf(("ERROR: out of memory!!"));
    505         SetLastError(ERROR_OUTOFMEMORY_W);
    506         return WAIT_FAILED_W;
    507     }
    508     for(i=0;i<cObjects;i++) {
    509         pHandles[i] = HMQueryHandleData(lphObjects[i]);
    510         if(pHandles[i] == NULL) {
    511             dprintf(("ERROR: handle %x not recognized", lphObjects[i]));
    512             SetLastError(ERROR_INVALID_HANDLE_W);
    513             return WAIT_FAILED_W;
    514         }
    515         if(!(pHandles[i]->dwAccess & SYNCHRONIZE_W) )
    516         {
    517             dprintf(("ERROR: Access denied (handle %x, index %d)!!", lphObjects[i], i));
    518             SetLastError(ERROR_ACCESS_DENIED_W);
    519             return WAIT_FAILED_W;
    520         }
    521         if(pHandles[i]->dwInternalType == HMTYPE_SEMAPHORE) {
    522             PSEM_INFO pSemInfo  = (PSEM_INFO)pHandles[i]->hHMHandle;
    523             dprintf(("KERNEL32: HMWaitForMultipleObjects: handle %3i: ODIN-%08xh, OS/2-%08xh",
    524                      i, lphObjects[i], pSemInfo->hev));
    525         }
    526         else
    527             dprintf(("KERNEL32: HMWaitForMultipleObjects: handle %3i: ODIN-%08xh, OS/2-%08xh",
    528                      i, lphObjects[i], pHandles[i]->hHMHandle));
    529 
    530     }
    531     j = 0;
    532     for(i=0;i<cObjects;i++) {
    533         if(pHandles[i]->dwInternalType == HMTYPE_SEMAPHORE) {
    534             PSEM_INFO pSemInfo  = (PSEM_INFO)pHandles[i]->hHMHandle;
    535 
    536             if(InterlockedDecrement(&pSemInfo->currentCount) >= 0) {
    537                 if(!fWaitAll) {
    538                     return WAIT_OBJECT_0_W + i;
    539                 }
    540             }
    541             else {
    542                 pSemRec[j].hsemCur = (HSEM)pSemInfo->hev;
    543                 pSemRec[j].ulUser = j;
    544                 j++;
    545             }
    546         }
    547         else {
    548             pSemRec[j].hsemCur = (HSEM)pHandles[i]->hHMHandle;
    549             pSemRec[j].ulUser = j;
    550             j++;
    551         }
    552     }
    553     rc = DosCreateMuxWaitSem(NULL, &hmux, j, pSemRec, (fWaitAll) ? DCMW_WAIT_ALL : DCMW_WAIT_ANY);
    554     if(rc) {
    555         dprintf(("DosCreateMuxWaitSem failed with rc %d", rc));
    556         SetLastError(error2WinError(rc));
    557         return WAIT_FAILED_W;
    558     }
    559     ulUser = -1;
    560     rc = WinWaitMuxWaitSem(hmux, dwTimeout, &ulUser);
    561     DosCloseMuxWaitSem(hmux);
    562     if(rc && rc != ERROR_INTERRUPT && rc != ERROR_TIMEOUT && rc != ERROR_SEM_OWNER_DIED) {
    563         dprintf(("DosWaitMuxWaitSem %x failed with rc %d", hmux, rc));
    564         SetLastError(error2WinError(rc));
    565         return WAIT_FAILED_W;
    566     }
    567     SetLastError(ERROR_SUCCESS_W);
    568     if(rc == ERROR_INTERRUPT || rc == ERROR_SEM_OWNER_DIED) {
    569         //TODO: add index of handle that caused the error....
    570         dprintf(("WAIT_ABANDONED_W"));
    571         return WAIT_ABANDONED_W;
    572     }
    573     else
    574     if(rc == ERROR_TIMEOUT) {
    575         dprintf(("WAIT_TIMEOUT_W"));
    576         return WAIT_TIMEOUT_W;
    577     }
    578     if(ulUser == -1) {
    579         dprintf(("WAIT_OBJECT_0_W+%d", cObjects));
    580         return WAIT_OBJECT_0_W + cObjects; //message waiting
    581     }
    582     dprintf(("WAIT_OBJECT_0_W+%d", ulUser));
    583     return WAIT_OBJECT_0_W + ulUser;
    584 }
    585 
    586 #endif
    587 
    588 #ifdef USE_OS2SEMAPHORES
    589 /*****************************************************************************
    590  * Name      : BOOL HMDeviceSemaphoreClass::WaitForMultipleObjects
    591  * Purpose   :
    592  * Variables :
    593  * Result    :
    594  * Remark    :
    595  * Status    :
    596  *
    597  * Author    : SvL
    598  *****************************************************************************/
    599 DWORD HMDeviceSemaphoreClass::WaitForMultipleObjects(PHMHANDLEDATA pHMHandleData,
    600                                                  DWORD   cObjects,
    601                                                  PHANDLE lphObjects,
    602                                                  BOOL    fWaitAll,
    603                                                  DWORD   dwTimeout)
    604 {
    605     return HMSemWaitForMultipleObjects(cObjects, lphObjects, fWaitAll, dwTimeout);
    606 }
    607 
    608 DWORD HMSemWaitForMultipleObjects(DWORD   cObjects,
    609                                   PHANDLE lphObjects,
    610                                   BOOL    fWaitAll,
    611                                   DWORD   dwTimeout)
    612 {
    613     PHMHANDLEDATA *pHandles;
    614     HMUX hmux;
    615     PSEMRECORD pSemRec;
    616     int i, j;
    617     APIRET rc;
    618     ULONG  ulUser;
    619 
    620     dprintf(("KERNEL32: WaitForMultipleObjects %d %x %d %x",
    621               cObjects, lphObjects, fWaitAll, dwTimeout));
    622 
    623     pHandles = (PHMHANDLEDATA *)alloca(cObjects * sizeof(PHMHANDLEDATA));
    624     pSemRec  = (PSEMRECORD)alloca(cObjects * sizeof(SEMRECORD));
    625     if(pHandles == NULL || pSemRec == NULL) {
    626         dprintf(("ERROR: out of memory!!"));
    627         SetLastError(ERROR_OUTOFMEMORY_W);
    628         return WAIT_FAILED_W;
    629     }
    630     for(i=0;i<cObjects;i++) {
    631         pHandles[i] = HMQueryHandleData(lphObjects[i]);
    632         if(pHandles[i] == NULL) {
    633             dprintf(("ERROR: handle %x not recognized", lphObjects[i]));
    634         }
    635         if(!(pHandles[i]->dwAccess & EVENT_MODIFY_STATE_W) )
    636         {
    637             dprintf(("ERROR: Access denied (handle %x, index %d)!!", lphObjects[i], i));
    638             SetLastError(ERROR_INVALID_HANDLE_W);
    639             return WAIT_FAILED_W;
    640         }
    641         if(pHandles[i]->dwInternalType == HMTYPE_SEMAPHORE) {
    642             PSEM_INFO pSemInfo  = (PSEM_INFO)pHandles[i]->hHMHandle;
    643             dprintf(("KERNEL32: HMWaitForMultipleObjects: handle %3i: ODIN-%08xh, OS/2-%08xh",
    644                      i, lphObjects[i], pSemInfo->hev));
    645         }
    646         else
    647             dprintf(("KERNEL32: HMWaitForMultipleObjects: handle %3i: ODIN-%08xh, OS/2-%08xh",
    648                      i, lphObjects[i], pHandles[i]->hHMHandle));
    649 
    650     }
    651     j = 0;
    652     for(i=0;i<cObjects;i++) {
    653         if(pHandles[i]->dwInternalType == HMTYPE_SEMAPHORE) {
    654             PSEM_INFO pSemInfo  = (PSEM_INFO)pHandles[i]->hHMHandle;
    655 
    656             if(InterlockedDecrement(&pSemInfo->currentCount) >= 0) {
    657                 if(!fWaitAll) {
    658                     return WAIT_OBJECT_0_W + i;
    659                 }
    660             }
    661             else {
    662                 pSemRec[j].hsemCur = (HSEM)pSemInfo->hev;
    663                 pSemRec[j].ulUser = j;
    664                 j++;
    665             }
    666         }
    667         else {
    668             pSemRec[j].hsemCur = (HSEM)pHandles[i]->hHMHandle;
    669             pSemRec[j].ulUser = j;
    670             j++;
    671         }
    672     }
    673     rc = DosCreateMuxWaitSem(NULL, &hmux, j, pSemRec, (fWaitAll) ? DCMW_WAIT_ALL : DCMW_WAIT_ANY);
    674     if(rc) {
    675         dprintf(("DosCreateMuxWaitSem failed with rc %d", rc));
    676         SetLastError(error2WinError(rc));
    677         return WAIT_FAILED_W;
    678     }
    679     rc = DosWaitMuxWaitSem(hmux, dwTimeout, &ulUser);
    680     DosCloseMuxWaitSem(hmux);
    681     if(rc && rc != ERROR_INTERRUPT && rc != ERROR_TIMEOUT && rc != ERROR_SEM_OWNER_DIED) {
    682         dprintf(("DosWaitMuxWaitSem %x failed with rc %d", hmux, rc));
    683         SetLastError(error2WinError(rc));
    684         return WAIT_FAILED_W;
    685     }
    686     SetLastError(ERROR_SUCCESS_W);
    687     if(rc == ERROR_INTERRUPT || rc == ERROR_SEM_OWNER_DIED) {
    688         //TODO: add index of handle that caused the error....
    689         return WAIT_ABANDONED_W;
    690     }
    691     else
    692     if(rc == ERROR_TIMEOUT) {
    693         return WAIT_TIMEOUT_W;
    694     }
    695     return WAIT_OBJECT_0_W + ulUser;
    696 }
    697 
    698 #endif
    699140
    700141/*****************************************************************************
     
    714155                                              LPLONG        lpPreviousCount)
    715156{
    716 #ifdef USE_OS2SEMAPHORES
    717   APIRET rc;
    718   ULONG count; 
    719  
    720   dprintf2(("KERNEL32: HandleManager::Semaphore::ReleaseSemaphore(%08xh,%08xh,%08xh)\n",
    721             pHMHandleData->hHMHandle,
    722             cReleaseCount,
    723             lpPreviousCount));
    724 
    725   if(!(pHMHandleData->dwAccess & SEMAPHORE_MODIFY_STATE_W) )
    726   {
    727       dprintf(("ERROR: Access denied!!"));
    728       SetLastError(ERROR_ACCESS_DENIED_W);
    729       return FALSE;
    730   }
    731 
    732   PSEM_INFO pSemInfo  = (PSEM_INFO)pHMHandleData->hHMHandle;
    733 
    734   if(InterlockedIncrement(&pSemInfo->currentCount) > 0) {
    735       //TODO: this is NOT thread safe:
    736       if(pSemInfo->currentCount > pSemInfo->maximumCount) {
    737           pSemInfo->currentCount = pSemInfo->maximumCount;
    738       }
    739       SetLastError(ERROR_SUCCESS_W);
    740       return TRUE; 
    741   }
    742 
    743   rc = DosResetEventSem(pSemInfo->hev, &count);
    744   if(rc && rc != ERROR_ALREADY_RESET) {
    745       dprintf(("DosResetEventSem %x failed with rc %d", pSemInfo->hev, rc));
    746       SetLastError(error2WinError(rc));
    747       return FALSE;
    748   }
    749   SetLastError(ERROR_SUCCESS_W);
    750   return TRUE;
    751 #else
    752157  dprintf(("KERNEL32: HandleManager::Semaphore::ReleaseSemaphore(%08xh,%08xh,%08xh)\n",
    753158           pHMHandleData->hHMHandle,
     
    758163                               cReleaseCount,
    759164                               lpPreviousCount));
    760 #endif
    761165}
    762166
    763167//******************************************************************************
    764 //Replaces illegal characters in semaphore name (or else OS/2 will return
    765 //ERROR_INVALID_NAME
    766168//******************************************************************************
    767 void FixSemName(char *lpszSemaphoreName)
    768 {
    769     while(TRUE) {
    770         switch(*lpszSemaphoreName) {
    771         case 0:
    772             return;
    773         case '?':
    774         case ':':
    775             *lpszSemaphoreName = '_';
    776             break;
    777         }
    778         lpszSemaphoreName++;
    779     }
    780 }
    781 //******************************************************************************
    782 //******************************************************************************
Note: See TracChangeset for help on using the changeset viewer.