void crHashtableReplace( CRHashTable *h, unsigned long key, void *data, CRHashtableCallback deleteFunc) { unsigned int index = crHash( key ); CRHashNode *temp; #ifdef CHROMIUM_THREADSAFE crLockMutex(&h->mutex); #endif for ( temp = h->buckets[index]; temp; temp = temp->next ) { if ( temp->key == key ) break; } #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&h->mutex); #endif if ( !temp ) { crHashtableAdd( h, key, data ); return; } #ifdef CHROMIUM_THREADSAFE crLockMutex(&h->mutex); #endif if ( temp->data && deleteFunc ) { (*deleteFunc)( temp->data ); } temp->data = data; #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&h->mutex); #endif }
GLint FEEDBACKSPU_APIENTRY feedbackspu_VBoxCreateContext( GLint con, const char *dpyName, GLint visual, GLint shareCtx ) { GLint ctx, slot; #ifdef CHROMIUM_THREADSAFE crLockMutex(&feedback_spu.mutex); #endif ctx = feedback_spu.child.VBoxCreateContext(con, dpyName, visual, shareCtx); /* find an empty context slot */ for (slot = 0; slot < feedback_spu.numContexts; slot++) { if (!feedback_spu.context[slot].clientState) { /* found empty slot */ break; } } if (slot == feedback_spu.numContexts) { feedback_spu.numContexts++; } feedback_spu.context[slot].clientState = crStateCreateContext(NULL, visual, NULL); feedback_spu.context[slot].clientCtx = ctx; #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&feedback_spu.mutex); #endif return ctx; }
static void ARRAYSPU_APIENTRY arrayspu_DestroyContext( GLint ctx ) { #ifdef CHROMIUM_THREADSAFE crLockMutex(&_ArrayMutex); #endif array_spu.child.DestroyContext(ctx); if (ctx) { int slot; for (slot=0; slot<array_spu.numContexts; ++slot) if (array_spu.context[slot].clientCtx == ctx) break; CRASSERT(slot < array_spu.numContexts); crStateDestroyContext(array_spu.context[slot].clientState); array_spu.context[slot].clientState = NULL; array_spu.context[slot].clientCtx = 0; } #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&_ArrayMutex); #endif }
static void ARRAYSPU_APIENTRY arrayspu_MakeCurrent( GLint window, GLint nativeWindow, GLint ctx ) { #ifdef CHROMIUM_THREADSAFE crLockMutex(&_ArrayMutex); #endif array_spu.child.MakeCurrent(window, nativeWindow, ctx); if (ctx) { int slot; for (slot=0; slot<array_spu.numContexts; ++slot) if (array_spu.context[slot].clientCtx == ctx) break; CRASSERT(slot < array_spu.numContexts); crStateMakeCurrent(array_spu.context[slot].clientState); } else { crStateMakeCurrent(NULL); } #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&_ArrayMutex); #endif }
static GLint ARRAYSPU_APIENTRY arrayspu_CreateContext( const char *dpyName, GLint visual, GLint shareCtx ) { GLint ctx, slot; #ifdef CHROMIUM_THREADSAFE crLockMutex(&_ArrayMutex); #endif ctx = array_spu.child.CreateContext(dpyName, visual, shareCtx); /* find an empty context slot */ for (slot = 0; slot < array_spu.numContexts; slot++) { if (!array_spu.context[slot].clientState) { /* found empty slot */ break; } } if (slot == array_spu.numContexts) { array_spu.numContexts++; } array_spu.context[slot].clientState = crStateCreateContext(NULL, visual, NULL); array_spu.context[slot].clientCtx = ctx; #ifdef CR_ARB_vertex_buffer_object array_spu.context[slot].clientState->bufferobject.retainBufferData = GL_TRUE; #endif #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&_ArrayMutex); #endif return ctx; }
GLuint PACKSPU_APIENTRY packspu_VBoxPackGetInjectID(GLint con) { GLuint ret; crLockMutex(&_PackMutex); { ThreadInfo *thread = NULL; if (CRPACKSPU_IS_WDDM_CRHGSMI()) { if (!con) { crError("connection expected!"); return 0; } thread = GET_THREAD_VAL_ID(con); } else { CRASSERT(!con); thread = GET_THREAD_VAL(); } CRASSERT(thread && thread->netServer.conn && thread->netServer.conn->type==CR_VBOXHGCM); ret = thread->netServer.conn->u32ClientID; } crUnlockMutex(&_PackMutex); return ret; }
static int packSPUCleanup(void) { int i; #ifdef CHROMIUM_THREADSAFE crLockMutex(&_PackMutex); #endif for (i=0; i<MAX_THREADS; ++i) { if (pack_spu.thread[i].inUse && pack_spu.thread[i].packer) { crPackDeleteContext(pack_spu.thread[i].packer); } } crFreeTSD(&_PackerTSD); crFreeTSD(&_PackTSD); #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&_PackMutex); # ifndef WINDOWS crFreeMutex(&_PackMutex); # endif #endif return 1; }
static void crSDPFree( CRConnection *conn, void *buf ) { CRSDPBuffer *sdp_buffer = (CRSDPBuffer *) buf - 1; CRASSERT( sdp_buffer->magic == CR_SDP_BUFFER_MAGIC ); conn->recv_credits += sdp_buffer->len; switch ( sdp_buffer->kind ) { case CRSDPMemory: #ifdef CHROMIUM_THREADSAFE crLockMutex(&cr_sdp.mutex); #endif if (cr_sdp.bufpool) { /* pool may have been deallocated just a bit earlier in response * to a SIGPIPE (Broken Pipe) signal. */ crBufferPoolPush( cr_sdp.bufpool, sdp_buffer, sdp_buffer->allocated ); } #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&cr_sdp.mutex); #endif break; case CRSDPMemoryBig: crFree( sdp_buffer ); break; default: crError( "Weird buffer kind trying to free in crSDPFree: %d", sdp_buffer->kind ); } }
static void * crSDPAlloc( CRConnection *conn ) { CRSDPBuffer *buf; #ifdef CHROMIUM_THREADSAFE crLockMutex(&cr_sdp.mutex); #endif buf = (CRSDPBuffer *) crBufferPoolPop( cr_sdp.bufpool, conn->buffer_size ); if ( buf == NULL ) { crDebug( "Buffer pool %p was empty, so I allocated %d bytes.\n\tI did so from the buffer: %p", cr_sdp.bufpool, (unsigned int)sizeof(CRSDPBuffer) + conn->buffer_size, &cr_sdp.bufpool ); buf = (CRSDPBuffer *) crAlloc( sizeof(CRSDPBuffer) + conn->buffer_size ); buf->magic = CR_SDP_BUFFER_MAGIC; buf->kind = CRSDPMemory; buf->pad = 0; buf->allocated = conn->buffer_size; } else { CRASSERT(buf->magic == CR_SDP_BUFFER_MAGIC); } #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&cr_sdp.mutex); #endif return (void *)( buf + 1 ); }
static void crFileFree( CRConnection *conn, void *buf ) { CRFileBuffer *file_buffer = (CRFileBuffer *) buf - 1; CRASSERT( file_buffer->magic == CR_FILE_BUFFER_MAGIC ); conn->recv_credits += file_buffer->len; switch ( file_buffer->kind ) { case CRFileMemory: #ifdef CHROMIUM_THREADSAFE crLockMutex(&cr_file.mutex); #endif crBufferPoolPush( cr_file.bufpool, file_buffer, conn->buffer_size ); #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&cr_file.mutex); #endif break; case CRFileMemoryBig: crFree( file_buffer ); break; default: crError( "Weird buffer kind trying to free in crFileFree: %d", file_buffer->kind ); } }
/** * Add a message node to the end of the message list. * \param list the message list * \param msg points to start of message buffer * \param len length of message, in bytes * \param conn connection associated with message (may be NULL) */ void crEnqueueMessage(CRMessageList *list, CRMessage *msg, unsigned int len, CRConnection *conn) { CRMessageListNode *node; #ifdef CHROMIUM_THREADSAFE crLockMutex(&list->lock); #endif node = (CRMessageListNode *) crAlloc(sizeof(CRMessageListNode)); node->mesg = msg; node->len = len; node->conn = conn; node->next = NULL; /* insert at tail */ if (list->tail) list->tail->next = node; else list->head = node; list->tail = node; list->numMessages++; #ifdef CHROMIUM_THREADSAFE crSignalCondition(&list->nonEmpty); crUnlockMutex(&list->lock); #endif }
/** * Simple logging. This will be called by either thread whenever an * interesting event occurs. */ void vncspuLog(int threadNum, const char *msg, int i) { #if SIMPLE_LOGGING static FILE *logFile = NULL; char tb[32]; int k; struct timeval tv; if (!logFile) { /* one time init */ logFile = fopen("/tmp/vncspu.log", "w"); crInitMutex(&vnc_spu.logLock); } crLockMutex(&vnc_spu.logLock); gettimeofday(&tv, NULL); tv.tv_sec = tv.tv_sec % 10; sprintf(tb, "%2u.%06u ", (unsigned) tv.tv_sec, (unsigned) tv.tv_usec); fputs(tb, logFile); for (k = 0; k < threadNum; k++) fputs(" ", logFile); fprintf(logFile, msg, i); fputs("\n", logFile); crUnlockMutex(&vnc_spu.logLock); #endif }
static void _crVBoxHGSMIFree(CRConnection *conn, void *buf) { CRVBOXHGSMIBUFFER *hgsmi_buffer = (CRVBOXHGSMIBUFFER *) buf - 1; CRASSERT(hgsmi_buffer->magic == CR_VBOXHGSMI_BUFFER_MAGIC); if (hgsmi_buffer->bIsBuf) { PVBOXUHGSMI_BUFFER pBuf = hgsmi_buffer->pBuffer; PCRVBOXHGSMI_CLIENT pClient = (PCRVBOXHGSMI_CLIENT)pBuf->pvUserData; pBuf->pfnUnlock(pBuf); _crVBoxHGSMIBufFree(pClient, pBuf); } else { /*@todo wrong len for redir buffers*/ conn->recv_credits += hgsmi_buffer->u32Len; #ifdef CHROMIUM_THREADSAFE crLockMutex(&g_crvboxhgsmi.mutex); #endif crBufferPoolPush(g_crvboxhgsmi.mempool, hgsmi_buffer, hgsmi_buffer->cbLock); #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&g_crvboxhgsmi.mutex); #endif } }
static void stubCheckWindowsState(void) { ContextInfo *context = stubGetCurrentContext(); CRASSERT(stub.trackWindowSize || stub.trackWindowPos); if (!context) return; #if defined(WINDOWS) && defined(VBOX_WITH_WDDM) if (stub.bRunningUnderWDDM) return; #endif #if defined(CR_NEWWINTRACK) && !defined(WINDOWS) crLockMutex(&stub.mutex); #endif stubCheckWindowState(context->currentDrawable, GL_TRUE); crHashtableWalk(stub.windowTable, stubCheckWindowsCB, context); #if defined(CR_NEWWINTRACK) && !defined(WINDOWS) crUnlockMutex(&stub.mutex); #endif }
GLboolean crHashtableGetDataKey(CRHashTable *pHash, void *pData, unsigned long *pKey) { int i; CRHashNode *entry; GLboolean rc = GL_FALSE; if (!pHash) return rc; #ifdef CHROMIUM_THREADSAFE crLockMutex(&pHash->mutex); #endif for (i = 0; i<CR_NUM_BUCKETS && !rc; i++) { entry = pHash->buckets[i]; while (entry) { if (entry->data == pData) { if (pKey) *pKey = entry->key; rc = GL_TRUE; break; } entry = entry->next; } } #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&pHash->mutex); #endif return rc; }
void FEEDBACKSPU_APIENTRY feedbackspu_MakeCurrent( GLint window, GLint nativeWindow, GLint ctx ) { #ifdef CHROMIUM_THREADSAFE crLockMutex(&feedback_spu.mutex); #endif feedback_spu.child.MakeCurrent(window, nativeWindow, ctx); if (ctx) { int slot; GLint oldmode; for (slot=0; slot<feedback_spu.numContexts; ++slot) if (feedback_spu.context[slot].clientCtx == ctx) break; CRASSERT(slot < feedback_spu.numContexts); crStateMakeCurrent(feedback_spu.context[slot].clientState); crStateGetIntegerv(GL_RENDER_MODE, &oldmode); if (oldmode!=feedback_spu.render_mode) { feedback_spu.self.RenderMode(oldmode); } } else { crStateMakeCurrent(NULL); } #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&feedback_spu.mutex); #endif }
void FEEDBACKSPU_APIENTRY feedbackspu_DestroyContext( GLint ctx ) { #ifdef CHROMIUM_THREADSAFE crLockMutex(&feedback_spu.mutex); #endif feedback_spu.child.DestroyContext(ctx); if (ctx) { int slot; for (slot=0; slot<feedback_spu.numContexts; ++slot) if (feedback_spu.context[slot].clientCtx == ctx) break; CRASSERT(slot < feedback_spu.numContexts); crStateDestroyContext(feedback_spu.context[slot].clientState); feedback_spu.context[slot].clientState = NULL; feedback_spu.context[slot].clientCtx = 0; } #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&feedback_spu.mutex); #endif }
void crHashtableWalk( CRHashTable *hash, CRHashtableWalkCallback walkFunc , void *dataPtr2) { int i; CRHashNode *entry, *next; if (!hash) return; #ifdef CHROMIUM_THREADSAFE crLockMutex(&hash->mutex); #endif for (i = 0; i < CR_NUM_BUCKETS; i++) { entry = hash->buckets[i]; while (entry) { /* save next ptr here, in case walkFunc deletes this entry */ next = entry->next; if (entry->data && walkFunc) { (*walkFunc)( entry->key, entry->data, dataPtr2 ); } entry = next; } } #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&hash->mutex); #endif }
static void *crFileAlloc( CRConnection *conn ) { CRFileBuffer *buf; #ifdef CHROMIUM_THREADSAFE crLockMutex(&cr_file.mutex); #endif buf = (CRFileBuffer *) crBufferPoolPop( cr_file.bufpool, conn->buffer_size ); if ( buf == NULL ) { crDebug( "Buffer pool was empty, so I allocated %d bytes", (int)(sizeof(CRFileBuffer) + conn->buffer_size) ); buf = (CRFileBuffer *) crAlloc( sizeof(CRFileBuffer) + conn->buffer_size ); buf->magic = CR_FILE_BUFFER_MAGIC; buf->kind = CRFileMemory; buf->pad = 0; buf->allocated = conn->buffer_size; } #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&cr_file.mutex); #endif return (void *)( buf + 1 ); }
static void crSDPSend( CRConnection *conn, void **bufp, const void *start, unsigned int len ) { CRSDPBuffer *sdp_buffer; unsigned int *lenp; if ( !conn || conn->type == CR_NO_CONNECTION ) return; if ( bufp == NULL ) { /* we are doing synchronous sends from user memory, so no need * to get fancy. Simply write the length & the payload and * return. */ const int sendable_len = conn->swap ? SWAP32(len) : len; crSDPWriteExact( conn, &sendable_len, sizeof(len) ); if ( !conn || conn->type == CR_NO_CONNECTION) return; crSDPWriteExact( conn, start, len ); return; } sdp_buffer = (CRSDPBuffer *)(*bufp) - 1; CRASSERT( sdp_buffer->magic == CR_SDP_BUFFER_MAGIC ); /* All of the buffers passed to the send function were allocated * with crSDPAlloc(), which includes a header with a 4 byte * length field, to insure that we always have a place to write * the length field, even when start == *bufp. */ lenp = (unsigned int *) start - 1; if (conn->swap) { *lenp = SWAP32(len); } else { *lenp = len; } if ( __sdp_write_exact( conn->sdp_socket, lenp, len + sizeof(int) ) < 0 ) { __sdp_dead_connection( conn ); } /* reclaim this pointer for reuse and try to keep the client from accidentally reusing it directly */ #ifdef CHROMIUM_THREADSAFE crLockMutex(&cr_sdp.mutex); #endif crBufferPoolPush( cr_sdp.bufpool, sdp_buffer, sdp_buffer->allocated ); /* Since the buffer's now in the 'free' buffer pool, the caller can't * use it any more. Setting bufp to NULL will make sure the caller * doesn't try to re-use the buffer. */ *bufp = NULL; #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&cr_sdp.mutex); #endif }
/* * Allocate a new ThreadInfo structure, setup a connection to the * server, allocate/init a packer context, bind this ThreadInfo to * the calling thread with crSetTSD(). * We'll always call this function at least once even if we're not * using threads. */ ThreadInfo *replicatespuNewThread( CRthread id ) { ThreadInfo *thread; #ifdef CHROMIUM_THREADSAFE_notyet crLockMutex(&_ReplicateMutex); #else CRASSERT(replicate_spu.numThreads == 0); #endif CRASSERT(replicate_spu.numThreads < MAX_THREADS); thread = &(replicate_spu.thread[replicate_spu.numThreads]); thread->id = id; thread->currentContext = NULL; /* connect to the server */ thread->server.name = crStrdup( replicate_spu.name ); thread->server.buffer_size = replicate_spu.buffer_size; if (replicate_spu.numThreads == 0) { replicatespuConnectToServer( &(thread->server) ); CRASSERT(thread->server.conn); replicate_spu.swap = thread->server.conn->swap; } else { /* a new pthread */ replicatespuFlushAll( &(replicate_spu.thread[0]) ); crNetNewClient( replicate_spu.thread[0].server.conn, &(thread->server)); CRASSERT(thread->server.conn); } /* packer setup */ CRASSERT(thread->packer == NULL); thread->packer = crPackNewContext( replicate_spu.swap ); CRASSERT(thread->packer); crPackInitBuffer( &(thread->buffer), crNetAlloc(thread->server.conn), thread->server.conn->buffer_size, thread->server.conn->mtu ); thread->buffer.canBarf = thread->server.conn->Barf ? GL_TRUE : GL_FALSE; crPackSetBuffer( thread->packer, &thread->buffer ); crPackFlushFunc( thread->packer, replicatespuFlush ); crPackFlushArg( thread->packer, (void *) thread ); crPackSendHugeFunc( thread->packer, replicatespuHuge ); crPackSetContext( thread->packer ); #ifdef CHROMIUM_THREADSAFE_notyet crSetTSD(&_ReplicateTSD, thread); #endif replicate_spu.numThreads++; #ifdef CHROMIUM_THREADSAFE_notyet crUnlockMutex(&_ReplicateMutex); #endif return thread; }
void PACKSPU_APIENTRY packspu_VBoxPackSetInjectID(GLuint id) { crLockMutex(&_PackMutex); { GET_THREAD(thread); CRASSERT(thread && thread->netServer.conn && thread->netServer.conn->type==CR_VBOXHGCM && thread->bInjectThread); thread->netServer.conn->u32InjectClientID = id; } crUnlockMutex(&_PackMutex); }
GLboolean crHashtableAllocRegisterKey( CRHashTable *h, GLuint key) { GLboolean fAllocated; #ifdef CHROMIUM_THREADSAFE crLockMutex(&h->mutex); #endif fAllocated = crHashIdPoolAllocId (h->idPool, key); #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&h->mutex); #endif return fAllocated; }
void PACKSPU_APIENTRY packspu_Flush( void ) { GET_THREAD(thread); int writeback=1; int found=0; if (!thread->bInjectThread) { crPackFlush(); if (packspuSyncOnFlushes()) { crPackWriteback(&writeback); packspuFlush( (void *) thread ); while (writeback) crNetRecv(); } } else { int i; crLockMutex(&_PackMutex); /*Make sure we process commands in order they should appear, so flush other threads first*/ for (i=0; i<MAX_THREADS; ++i) { if (pack_spu.thread[i].inUse && (thread != &pack_spu.thread[i]) && pack_spu.thread[i].netServer.conn && pack_spu.thread[i].packer && pack_spu.thread[i].packer->currentBuffer) { packspuFlush((void *) &pack_spu.thread[i]); if (pack_spu.thread[i].netServer.conn->u32ClientID == thread->netServer.conn->u32InjectClientID) { found=1; } } } if (!found) { /*Thread we're supposed to inject commands for has been detached, so there's nothing to sync with and we should just pass commands through our own connection. */ thread->netServer.conn->u32InjectClientID=0; } packspuFlush((void *) thread); crUnlockMutex(&_PackMutex); } }
GLuint PACKSPU_APIENTRY packspu_VBoxPackGetInjectID(void) { GLuint ret; crLockMutex(&_PackMutex); { GET_THREAD(thread); CRASSERT(thread && thread->netServer.conn && thread->netServer.conn->type==CR_VBOXHGCM); ret = thread->netServer.conn->u32ClientID; } crUnlockMutex(&_PackMutex); return ret; }
void PACKSPU_APIENTRY packspu_VBoxPackSetInjectThread(void) { crLockMutex(&_PackMutex); { int i; GET_THREAD(thread); CRASSERT(!thread); CRASSERT((pack_spu.numThreads>0) && (pack_spu.numThreads<MAX_THREADS)); for (i=0; i<MAX_THREADS; ++i) { if (!pack_spu.thread[i].inUse) { thread = &pack_spu.thread[i]; break; } } CRASSERT(thread); thread->inUse = GL_TRUE; thread->id = crThreadID(); thread->currentContext = NULL; thread->bInjectThread = GL_TRUE; thread->netServer.name = crStrdup(pack_spu.name); thread->netServer.buffer_size = 64 * 1024; crNetNewClient(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn, &(thread->netServer)); CRASSERT(thread->netServer.conn); CRASSERT(thread->packer == NULL); thread->packer = crPackNewContext( pack_spu.swap ); CRASSERT(thread->packer); crPackInitBuffer(&(thread->buffer), crNetAlloc(thread->netServer.conn), thread->netServer.conn->buffer_size, thread->netServer.conn->mtu); thread->buffer.canBarf = thread->netServer.conn->Barf ? GL_TRUE : GL_FALSE; crPackSetBuffer( thread->packer, &thread->buffer ); crPackFlushFunc( thread->packer, packspuFlush ); crPackFlushArg( thread->packer, (void *) thread ); crPackSendHugeFunc( thread->packer, packspuHuge ); crPackSetContext( thread->packer ); crSetTSD(&_PackTSD, thread); pack_spu.numThreads++; } crUnlockMutex(&_PackMutex); }
void crHashtableDelete( CRHashTable *h, unsigned long key, CRHashtableCallback deleteFunc ) { unsigned int index = crHash( key ); CRHashNode *temp, *beftemp = NULL; #ifdef CHROMIUM_THREADSAFE crLockMutex(&h->mutex); #endif for ( temp = h->buckets[index]; temp; temp = temp->next ) { if ( temp->key == key ) break; beftemp = temp; } if ( !temp ) { #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&h->mutex); #endif return; /* not an error */ } if ( beftemp ) beftemp->next = temp->next; else h->buckets[index] = temp->next; h->num_elements--; if (temp->data && deleteFunc) { (*deleteFunc)( temp->data ); } crFree( temp ); crHashIdPoolFreeBlock( h->idPool, key, 1 ); #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&h->mutex); #endif }
void crHashtableAdd( CRHashTable *h, unsigned long key, void *data ) { CRHashNode *node = (CRHashNode *) crCalloc( sizeof( CRHashNode ) ); #ifdef CHROMIUM_THREADSAFE crLockMutex(&h->mutex); #endif node->key = key; node->data = data; node->next = h->buckets[crHash( key )]; h->buckets[ crHash( key ) ] = node; h->num_elements++; crHashIdPoolAllocId (h->idPool, key); #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&h->mutex); #endif }
static void crFileSend( CRConnection *conn, void **bufp, const void *start, unsigned int len ) { CRFileBuffer *file_buffer; unsigned int *lenp; if ( bufp == NULL ) { /* we are doing synchronous sends from user memory, so no need * to get fancy. Simply write the length & the payload and * return. */ if (conn->swap) { len = SWAP32(len); } crFileWriteExact( conn, &len, sizeof(len) ); crFileWriteExact( conn, start, len ); return; } file_buffer = (CRFileBuffer *)(*bufp) - 1; CRASSERT( file_buffer->magic == CR_FILE_BUFFER_MAGIC ); /* All of the buffers passed to the send function were allocated * with crFileAlloc(), which includes a header with a 4 byte * length field, to insure that we always have a place to write * the length field, even when start == *bufp. */ lenp = (unsigned int *) start - 1; *lenp = len; crFileWriteExact(conn, lenp, len + sizeof(int) ); /* reclaim this pointer for reuse and try to keep the client from accidentally reusing it directly */ #ifdef CHROMIUM_THREADSAFE crLockMutex(&cr_file.mutex); #endif crBufferPoolPush( cr_file.bufpool, file_buffer, conn->buffer_size ); #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&cr_file.mutex); #endif *bufp = NULL; }
/** * Remove first message node from message list and return it. * Don't block. * \return 1 if message was dequeued, 0 otherwise. */ static int crDequeueMessageNoBlock(CRMessageList *list, CRMessage **msg, unsigned int *len, CRConnection **conn) { int retval; #ifdef CHROMIUM_THREADSAFE crLockMutex(&list->lock); #endif if (list->head) { CRMessageListNode *node = list->head; /* unlink the node */ list->head = node->next; if (!list->head) { /* empty list */ list->tail = NULL; } *msg = node->mesg; *len = node->len; if (conn) *conn = node->conn; list->numMessages--; crFree(node); retval = 1; } else { *msg = NULL; *len = 0; retval = 0; } #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&list->lock); #endif return retval; }