Ignore:
Timestamp:
Jun 23, 2001, 6:59:28 PM (24 years ago)
Author:
sandervl
Message:

semaphore updates

File:
1 edited

Legend:

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

    r6079 r6084  
    1 /* $Id: hmsemaphore.cpp,v 1.7 2001-06-23 07:45:43 sandervl Exp $ */
     1/* $Id: hmsemaphore.cpp,v 1.8 2001-06-23 16:59:28 sandervl Exp $ */
    22
    33/*
     
    3434#define INCL_DOSSEMAPHORES
    3535#define INCL_DOSERRORS
     36#define INCL_WIN
    3637#include <os2wrap.h>
    3738#include <win32type.h>
     
    6364#endif
    6465
    65 #ifdef USE_OS2SEMAPHORES
    66 typedef struct {
    67     LONG currentCount;
    68     LONG maximumCount;
    69     LONG refCount;
    70     HEV  hev;
    71 } SEM_INFO, *PSEM_INFO;
    72 #endif
    73 
    7466/*****************************************************************************
    7567 * Defines                                                                   *
     
    125117      strcat(szSemName, lpszSemaphoreName);
    126118      lpszSemaphoreName = szSemName;
     119      FixSemName((char *)lpszSemaphoreName);
    127120  }
    128121  rc = DosCreateEventSem(lpszSemaphoreName, &hev, DCE_POSTONE, lInitialCount);
     
    202195  strcpy(szSemName, "\\SEM32\\");
    203196  strcat(szSemName, lpszSemaphoreName);
     197  FixSemName(szSemName);
    204198  rc = DosOpenEventSem(szSemName, &hev);
    205199  if(rc) {
     
    418412                                                        DWORD      dwWakeMask)
    419413{
    420     dprintf(("KERNEL32: ERROR: HandleManager::DeviceHandler::MsgWaitForMultipleObjects %08x %d %x %d %d %x",
    421               pHMHandleData->hHMHandle, nCount, pHandles, fWaitAll, dwMilliseconds, dwWakeMask));
    422 
    423     if(!(pHMHandleData->dwAccess & SYNCHRONIZE_W) )
    424     {
    425         dprintf(("ERROR: Access denied!!"));
    426         SetLastError(ERROR_ACCESS_DENIED_W);
     414    return HMSemMsgWaitForMultipleObjects(nCount, pHandles, fWaitAll, dwMilliseconds, dwWakeMask);
     415}
     416
     417DWORD 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: 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: 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: handle %3i: 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"));
     485            return WAIT_ABANDONED_W;
     486        }
     487        else
     488        if(rc == ERROR_TIMEOUT) {
     489            dprintf(("WAIT_TIMEOUT_W"));
     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"));
     496            return WAIT_OBJECT_0_W + 1;
     497        }
     498        dprintf(("WAIT_OBJECT_0_W+1"));
     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);
    427506        return WAIT_FAILED_W;
    428507    }
    429 
    430     return WAIT_FAILED_W;
    431 }
     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
    432586#endif
    433587
     
    449603                                                 DWORD   dwTimeout)
    450604{
    451     dprintf(("KERNEL32: ERROR: HandleManager::DeviceHandler::WaitForMultipleObjects %08x %d %x %d %x",
    452               pHMHandleData->hHMHandle, cObjects, lphObjects, fWaitAll, dwTimeout));
    453 
    454     if(!(pHMHandleData->dwAccess & SYNCHRONIZE_W) )
    455     {
    456         dprintf(("ERROR: Access denied!!"));
    457         SetLastError(ERROR_ACCESS_DENIED_W);
     605    return HMSemWaitForMultipleObjects(cObjects, lphObjects, fWaitAll, dwTimeout);
     606}
     607
     608DWORD 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);
    458628        return WAIT_FAILED_W;
    459629    }
    460 
    461     return WAIT_FAILED_W;
    462 }
     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
    463698#endif
    464699
     
    507742
    508743  rc = DosResetEventSem(pSemInfo->hev, &count);
    509   if(rc) {
     744  if(rc && rc != ERROR_ALREADY_RESET) {
    510745      dprintf(("DosResetEventSem %x failed with rc %d", pSemInfo->hev, rc));
    511746      SetLastError(error2WinError(rc));
     
    526761}
    527762
     763//******************************************************************************
     764//Replaces illegal characters in semaphore name (or else OS/2 will return
     765//ERROR_INVALID_NAME
     766//******************************************************************************
     767void 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.