STATIC Bool GWENG_QueueFlush(EcmtQueueConnection* qc) { if (qc->header && BUFFER_Size(&qc->buf) >= ECMT_MSG_HEADER_SIZE) { char* hdr = BUFFER_Access(&qc->buf); if (GWENG_ParseEcmtHeader(hdr, &qc->uid, &qc->datalen)) { qc->header = False; qc->datalen -= ECMT_MSG_HEADER_SIZE; BUFFER_Skip(&qc->buf, ECMT_MSG_HEADER_SIZE); } else { /* There shoudn't be any garbage here */ ASSMSG("Garbage in GWENG_QueueFlush"); return False; } } if (!qc->header && BUFFER_Size(&qc->buf) >= qc->datalen) { char* data = BUFFER_Access(&qc->buf); GWENG_QueueAdd(qc->queue, qc->uid, data, qc->datalen); BUFFER_Skip(&qc->buf, qc->datalen); qc->header = True; qc->datalen = 0; qc->uid = 0; return True; } return False; }
/** * Yet another assertion handler. */ void DEBUG_AssertFormat(const char * file, long line, Str format, ...) { char msg[512]; #ifdef UNICODE Char msg2[COUNT(msg)]; #else /* !UNICODE */ # define msg2 msg #endif /* UNICODE */ #if defined(_WIN32) && !defined(_NT_KERNEL) ULONG lastError = GetLastError(); # ifdef _USE_EXCEPTION_HANDLING __try { # endif /* _USE_EXCEPTION_HANDLING */ #endif /* _WIN32) && !_NT_KERNEL */ int n; va_list va; va_start(va, format); /* format the message */ n = Vsnprintf(msg2,COUNT(msg2),format,va); #ifdef UNICODE msg[0] = 0; msg2[COUNT(msg2)-1] = 0; wcstombs(msg, msg2, COUNT(msg)); msg[COUNT(msg)-1] = 0; #endif /* UNICODE */ /* if the output string is REALLY long, terminate it with ... */ if (n >= COUNT(msg)-1 || n < 0) { n = COUNT(msg)-1; msg[n--] = 0; msg[n--] = '.'; msg[n--] = '.'; msg[n--] = '.'; msg[n--] = ' '; } else { msg[COUNT(msg)-1] = 0; } va_end(va); #if defined(_WIN32) && !defined(_NT_KERNEL) # ifdef _USE_EXCEPTION_HANDLING } __except(EXCEPTION_EXECUTE_HANDLER) { /* NOTE: ASSMSG1 macro would recursively invoke this function */ TRACE1("EXCEPTION %08lX in DEBUG_AssertFormat\n",GetExceptionCode()); ASSMSG("EXCEPTION in DEBUG_AssertFormat"); } # endif /* _USE_EXCEPTION_HANDLING */ DEBUG_Assert(msg, file, line); SetLastError(lastError); #else DEBUG_Assert(msg, file, line); #endif /* _WIN32) && !_NT_KERNEL */ }
/** * Returns the next element from the collection */ IElement ITR_Next(Iterator * itr) { if (itr->type->hasNext(itr)) { itr->flags |= ITR_ACTIVE; itr->flags &= ~ITR_REMOVED; return (itr->last = itr->type->next(itr)); } else { ASSMSG("Unexpected ITR_Next call"); return NULL; } }
STATIC Bool EXPAT_CheckFeatures(void) { const XML_Feature* f; for (f = XML_GetFeatureList(); f->feature != XML_FEATURE_END; f++) { if (f->feature == XML_FEATURE_UNICODE_WCHAR_T || f->feature == XML_FEATURE_UNICODE) { ASSMSG("SLIB and EXPAT are incompatible"); return False; } } return True; }
/** * 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; }
/** * Waits until the specified thread terminates */ Bool THREAD_Join(ThrID thr) { Bool success = False; ASSERT(THREAD_IsInited()); /* make sure that this isn't a pseudo-handle created by THREAD_Self */ if (!THREAD_IsFakeID(thr)) { ASSERT(!IsBadWritePtr(thr, sizeof(thr))); if (!IsBadWritePtr(thr, sizeof(thr))) { ASSERT(thr->signature == ThrData_Signature); ASSERT(thr->refCount > 0); ASSERT(!thr->detached); if (thr->signature == ThrData_Signature && thr->refCount > 0 && !thr->detached) { ASSERT(WIN32_IsThread(thr->handle)); /* thread can't join itself */ if (!THREAD_IsSelf(thr)) { /* WaitForSingleObject on a thread handle hangs forever * if invoked from a DLL entry point. That's why we are * using our own exit event here */ HANDLE h[2]; h[0] = thr->exitEvent.handle; h[1] = thr->handle; WaitForMultipleObjects(COUNT(h), h, FALSE, INFINITE); if (EVENT_State(&thr->exitEvent) == EVENT_NOT_SIGNALED) { TRACE1("SLIB: thread %d was killed\n",thr->thrid); THREAD_Deref(thr); } THREAD_Deref(thr); success = True; } else { ASSMSG("You've got a DEADLOCK, idiot!"); } } } } else { TRACE("SLIB: can't join a thread not created by THREAD_Create\n"); } return success; }
STATIC Bool GWENG_QueueWrite(EcmtConnection* c, const void* data, int size) { EcmtQueueConnection* qc = CAST(c,EcmtQueueConnection,connection); /* * Try to avoid copying. Most of the time we can safely do that because * both header and data are written as single chunks. However, if they * are not so nicely packaged, we have plan B. */ if (!BUFFER_Size(&qc->buf)) { if (qc->header && size>=ECMT_MSG_HEADER_SIZE) { if (GWENG_ParseEcmtHeader(data, &qc->uid, &qc->datalen)) { data = ((char*)data) + ECMT_MSG_HEADER_SIZE; size -= ECMT_MSG_HEADER_SIZE; qc->datalen -= ECMT_MSG_HEADER_SIZE; qc->header = False; } else { /* There shoudn't be any garbage here */ ASSMSG("Garbage in GWENG_QueueWrite"); return False; } } if (!qc->header && size >= qc->datalen) { GWENG_QueueAdd(qc->queue, qc->uid, data, qc->datalen); data = ((char*)data) + qc->datalen; size -= qc->datalen; qc->uid = 0; qc->datalen = 0; qc->header = True; } } if (size > 0) { /* Plan B */ if (BUFFER_Put(&qc->buf, data, size, False) == size) { while (GWENG_QueueFlush(qc)); } else { return False; } } return True; }
STATIC int GWENG_QueueRead(EcmtConnection* c, void* buf, int size) { /* should never be invoked */ ASSMSG("GWENG_QueueRead"); return False; }