Esempio n. 1
0
/**
 * Release the mutex.
 */
void MUTEX_Unlock(Mutex * m)
{
    if (!ReleaseMutex(m->handle)) {
        TRACE1("ERROR: thr %08lX can't release mutex\n",GetCurrentThreadId());
        ASSMSG1("ReleaseMutex() failed, error %lu", GetLastError());
    }
}
Esempio n. 2
0
/**
 * Win32-specific thread proc
 */
STATIC DWORD WINAPI WIN32_ThreadProc(LPVOID arg)
{
    ThrData * thr = arg;

    /* This must succeed since we are not allocating any memory */
    VERIFY(VECTOR_Init(&thr->cleanupList,0,NULL,NULL));

#ifdef _USE_EXCEPTION_HANDLING
    __try {
#endif /* _USE_EXCEPTION_HANDLING */

        ASSERT(TlsGetValue(WIN32_TLS_ThrID) == NULL);
        VERIFY(TlsSetValue(WIN32_TLS_ThrID, thr));
        if (WIN32_TLS_ThrID != TLS_OUT_OF_INDEXES) {
            ASSERT(TlsGetValue(WIN32_TLS_Data) == NULL);
            VERIFY(TlsSetValue(WIN32_TLS_Data, thr));
        }

        (*thr->proc)(thr->arg);

#ifdef _USE_EXCEPTION_HANDLING
    } __except(EXCEPTION_EXECUTE_HANDLER) {
        ASSMSG1("EXCEPTION %08lX in thread proc!",GetExceptionCode());
    }
#endif /* _USE_EXCEPTION_HANDLING */

    THREAD_Cleanup(thr);
    return 0;
}
Esempio n. 3
0
/**
 * Reset state to non-signaled.
 */
Bool EVENT_Reset(Event * e) 
{
    if (!ResetEvent(e->handle)) {
        ASSMSG1("ResetEvent() failed, error %lu", GetLastError());
        return False;
    }
    return True;
}
Esempio n. 4
0
/**
 * Notify all waiters and reset state to non-signaled
 */
Bool EVENT_Pulse(Event * e) 
{
    if (!PulseEvent(e->handle)) {
        ASSMSG1("PulseEvent() failed, error %lu", GetLastError());
        return False;
    }
    return True;
}
Esempio n. 5
0
/**
 * Initialize a mutex. Returns False if initialization fails.
 */
Bool MUTEX_Init(Mutex * m)
{
    m->handle = CreateMutex(NULL, False, NULL);
    if (!m) {
        ASSMSG1("CreateMutex() failed, error %lu", GetLastError());
        return False;
    }
    return True;
}
Esempio n. 6
0
/**
 * Sets blocking mode for the socket
 */
Bool SOCKET_Block(Socket s, Bool block)
{
    unsigned long arg = (!block);
    if (ioctlsocket(s, FIONBIO, &arg) >= 0) {
        return True;
    } else {
        ASSMSG1("ioctl(FIONBIO) failed, err %d",SOCKET_GetLastError());
        return False;
    }
}
Esempio n. 7
0
/**
 * Wait for event to become signaled.
 */
WaitState EVENT_Wait(Event * e) 
{
    DWORD status = WaitForSingleObject(e->handle, INFINITE);
    if (status == WAIT_OBJECT_0) {
        return WAIT_STATE_OK;
    } else {
        TRACE1("WaitForSingleObject() status %08lX\n",status);
        ASSMSG1("WaitForSingleObject() failed, error %d",GetLastError());
        return WAIT_STATE_ERROR;
    }
}
Esempio n. 8
0
/**
 * Locks the mutex. If mutex is already locked, waits until it becomes
 * available. Returns True if mutex has been successfully acquired, 
 * False otherwise.
 */
Bool MUTEX_Lock(Mutex * m)
{
    DWORD status = WaitForSingleObject(m->handle,INFINITE);
    switch (status) {
        case WAIT_ABANDONED_0:
            ASSMSG("Mutex was abandoned!");
            /* fall through */
        case WAIT_OBJECT_0: return True;
        case WAIT_TIMEOUT:  return False;
    }
    TRACE1("WaitForSingleObject() status %08lX\n",status);
    ASSMSG1("WaitForSingleObject() failed, error %d",GetLastError());
    return False;
}
Esempio n. 9
0
/**
 * This function is invoked when one of the modules has failed to initialize.
 * Never returns. Prints an error message and calls abort()
 */
void SLIB_Abort(Str module)
{
    Error(TEXT("Cannot initialize %s module, exiting...\n"),module);
    ASSMSG1("Cannot initialize %s module",module);

    /* should panic in kernel mode? */
#ifndef __KERNEL__
#  ifdef _WIN32_WCE
    exit(-1);
#  else /* !_WIN32_WCE */
    abort();
#  endif /* !_WIN32_WCE */
#endif /* __KERNEL__ */
}
Esempio n. 10
0
/**
 * Wait for event to become signaled.
 */
WaitState EVENT_TimeWait(Event * e, long ms) 
{
    if (ms < 0) {
        return EVENT_Wait(e);
    } else {
        DWORD status = WaitForSingleObject(e->handle, ms);
        switch (status) {
        case WAIT_OBJECT_0:  return WAIT_STATE_OK;
        case WAIT_TIMEOUT:   return WAIT_STATE_TIMEOUT;
        }
        TRACE1("WaitForSingleObject() status %08lX\n",status);
        ASSMSG1("WaitForSingleObject() failed, error %d",GetLastError());
        return WAIT_STATE_ERROR;
    }
}
Esempio n. 11
0
/**
 * Destroys thread local variables, sets exit event and dereferences
 * the thread handle.
 */
STATIC void THREAD_Cleanup(ThrData* thr)
{
    /* invoke destructors for thread local variables */
    int i, n = 1;
    for (i=0; i<MAX_DESTRUCTOR_ITERATIONS && n > 0; i++) {
        int k;
        n = 0;
        for (k=0; k<VECTOR_Size(&thr->cleanupList); k++) {
            ThrKey key = VECTOR_Get(&thr->cleanupList, k);
            void * value = TlsGetValue(key->index);
            if (value) {
                TlsSetValue(key->index, NULL);
#ifdef _USE_EXCEPTION_HANDLING
                __try {
#endif /* _USE_EXCEPTION_HANDLING */

                    key->clean(value);
                    ASSERT(!TlsGetValue(key->index));

#ifdef _USE_EXCEPTION_HANDLING
                } __except(EXCEPTION_EXECUTE_HANDLER) {
                    TlsSetValue(key->index,NULL);
                    ASSMSG1("EXCEPTION %08lX in cleanup proc!",
                            GetExceptionCode());
                }
#endif /* _USE_EXCEPTION_HANDLING */
                n++;
            }
        }
    }

    ASSERT(i<MAX_DESTRUCTOR_ITERATIONS);

    /* Dereference ThrKey structures */
    while ((n = VECTOR_Size(&thr->cleanupList)) > 0) {
        ThrKey key = VECTOR_Remove(&thr->cleanupList, n-1);
        if (InterlockedDecrement(&key->ref) == 0) {
            ASSERT(key->index == TLS_OUT_OF_INDEXES);
            MEM_Free(key);
        }
    }

    InterlockedDecrement(&WIN32_ThreadCount);
    VECTOR_Destroy(&thr->cleanupList);
    EVENT_Set(&thr->exitEvent);
    THREAD_Deref(thr);
}
Esempio n. 12
0
/**
 * Handles ECMT packet coming from MIDP debug plugin
 */
STATIC void GWENG_MidpHandleEcmtPacket(EcmtGateway* gw,
                                       MidpSession* midp, 
                                       const I8u* pkt, 
                                       int pktlen)
{
    I8u opcode = pkt[ECMT_MIDP_DEBUG_HEADER_OPCODE_OFFSET];
    switch (opcode)
    {
    case ECMT_MIDP_DEBUG_OPCODE_SEND:
        ASSERT(pktlen >= ECMT_MIDP_DEBUG_SEND_MIN_SIZE);
        if (pktlen >= ECMT_MIDP_DEBUG_SEND_MIN_SIZE) {
            I32u cid = htonl(*((I32u*)(pkt+ECMT_MIDP_DEBUG_SEND_CID_OFFSET)));
            I32u seq = htonl(*((I32u*)(pkt+ECMT_MIDP_DEBUG_SEND_SEQ_OFFSET)));
            MidpConnection* conn = HASH_Get(&midp->connMap,(HashKey)cid);
            if (conn) {
                if (conn->inCount == seq) {
                    XRpcData data;
                    XRpcContainer* params;
                    conn->inCount++; /* increment sequence number */
                    data.ptr = (I8u*)pkt + ECMT_MIDP_DEBUG_SEND_DATA_OFFSET;
                    data.size = pktlen - ECMT_MIDP_DEBUG_SEND_DATA_OFFSET;
                    TRACE4("GW: MidpReceive(%08x.%08x.%u, %d bytes)\n",
                        midp->key.xrpcSession, midp->key.xrpcSid, cid,
                        data.size);
                    DEBUG_ONLY(PRINT_Dump(DEBUG_Trace,data.ptr,data.size,0));
                    params = GWENG_CreateXRpcParams(midp,
                        ECMTGW_SEI_SEND_SID_PARAM, 
                        ECMTGW_SEI_SEND_CID_PARAM, cid);
                    if (params) {
                        XRpcElement* dataElem = _XRPC_CreateBinaryElement(
                            data.ptr, data.size);
                        if (dataElem) {
                            if (XRPC_SetElementName(dataElem,
                                ECMTGW_SEI_SEND_DATA_PARAM) &&
                                XRPC_AddElement(params, dataElem)) {
                                /* submit the call */
                                GWENG_SubmitAsyncCall(midp, 
                                    ECMTGW_SEI_SEND_METHOD, 
                                    params);
                                break;
                            } else {
                                XRPC_FreeElement(dataElem);
                            }
                        }
                        XRPC_FreeContainer(params);
                    }
                    /* Terminate connection? That would probably fail too */
                } else {
                    TRACE2("GW: SEQ mismatch (expected %u, found %u)\n",
                        conn->inCount, seq);
                    GWENG_MidpResetConn(gw, midp, cid, True, True);
                }
            } else {
                TRACE1("GW: invalid conn id %u from Ecmt\n",cid);
                GWENG_MidpResetConn(gw, midp, cid, True, False);
            }
        }
        break;

    case ECMT_MIDP_DEBUG_OPCODE_CLOSE:
        ASSERT(pktlen == ECMT_MIDP_DEBUG_CLOSE_SIZE);
        TRACE1("GW: closing session 0x%08lx (via ECMT)\n",midp->sid);
        GWENG_SubmitAsyncCall(midp,
            ECMTGW_SEI_CLOSE_METHOD,
            GWENG_CreateXRpcParams(midp,
                ECMTGW_SEI_CLOSE_SID_PARAM, 
                NULL, 0));
        break;

    case ECMT_MIDP_DEBUG_OPCODE_RESET:
        ASSERT(pktlen == ECMT_MIDP_DEBUG_RESET_SIZE);
        if (pktlen == ECMT_MIDP_DEBUG_RESET_SIZE) {
            I32u cid = htonl(*((I32u*)(pkt+ECMT_MIDP_DEBUG_RESET_CID_OFFSET)));
            GWENG_SubmitAsyncCall(midp,
                ECMTGW_SEI_RESET_METHOD,
                GWENG_CreateXRpcParams(midp,
                    ECMTGW_SEI_RESET_SID_PARAM, 
                    ECMTGW_SEI_RESET_CID_PARAM, cid));
        }
        break;

    default:
        ASSMSG1("GW: unexpected opcode %u",opcode);
        break;
    }
}