void *msConnPoolRequest( layerObj *layer ) { int i; const char* close_connection; if( layer->connection == NULL ) return NULL; /* check if we must always create a new connection */ close_connection = msLayerGetProcessingKey( layer, "CLOSE_CONNECTION" ); if( close_connection && strcasecmp(close_connection,"ALWAYS") == 0 ) return NULL; msAcquireLock( TLOCK_POOL ); for( i = 0; i < connectionCount; i++ ) { connectionObj *conn = connections + i; if( layer->connectiontype == conn->connectiontype && strcasecmp( layer->connection, conn->connection ) == 0 && (conn->ref_count == 0 || conn->thread_id == msGetThreadId()) && conn->lifespan != MS_LIFE_SINGLE) { void *conn_handle = NULL; conn->ref_count++; conn->thread_id = msGetThreadId(); conn->last_used = time(NULL); if( layer->debug ) { msDebug( "msConnPoolRequest(%s,%s) -> got %p\n", layer->name, layer->connection, conn->conn_handle ); conn->debug = layer->debug; } conn_handle = conn->conn_handle; msReleaseLock( TLOCK_POOL ); return conn_handle; } } msReleaseLock( TLOCK_POOL ); return NULL; }
/* msDebugCleanup() ** ** Called by msCleanup to remove info related to this thread. */ void msDebugCleanup() { /* make sure file is closed */ msCloseErrorFile(); #ifdef USE_THREAD { int thread_id = msGetThreadId(); debugInfoObj *link; msAcquireLock( TLOCK_DEBUGOBJ ); /* find link for this thread */ for( link = debuginfo_list; link != NULL && link->thread_id != thread_id && link->next != NULL && link->next->thread_id != thread_id; link = link->next ) {} if( link->thread_id == thread_id ) { /* presumably link is at head of list. */ if( debuginfo_list == link ) debuginfo_list = link->next; free( link ); } else if( link->next != NULL && link->next->thread_id == thread_id ) { debugInfoObj *next_link = link->next; link->next = link->next->next; free( next_link ); } msReleaseLock( TLOCK_DEBUGOBJ ); } #endif }
debugInfoObj *msGetDebugInfoObj() { debugInfoObj *link; int thread_id; debugInfoObj *ret_obj; msAcquireLock( TLOCK_DEBUGOBJ ); thread_id = msGetThreadId(); /* find link for this thread */ for( link = debuginfo_list; link != NULL && link->thread_id != thread_id && link->next != NULL && link->next->thread_id != thread_id; link = link->next ) {} /* If the target thread link is already at the head of the list were ok */ if( debuginfo_list != NULL && debuginfo_list->thread_id == thread_id ) { } /* We don't have one ... initialize one. */ else if( link == NULL || link->next == NULL ) { debugInfoObj *new_link; new_link = (debugInfoObj *) malloc(sizeof(debugInfoObj)); if (new_link != NULL) { new_link->next = debuginfo_list; new_link->thread_id = thread_id; new_link->global_debug_level = MS_DEBUGLEVEL_ERRORSONLY; new_link->debug_mode = MS_DEBUGMODE_OFF; new_link->errorfile = NULL; new_link->fp = NULL; } else msSetError(MS_MEMERR, "Out of memory allocating %u bytes.\n", "msGetDebugInfoObj()", sizeof(debugInfoObj)); debuginfo_list = new_link; } /* If the link is not already at the head of the list, promote it */ else if( link != NULL && link->next != NULL ) { debugInfoObj *target = link->next; link->next = link->next->next; target->next = debuginfo_list; debuginfo_list = target; } ret_obj = debuginfo_list; msReleaseLock( TLOCK_DEBUGOBJ ); return ret_obj; }
/* msResetErrorList() ** ** Clear the list of error objects. */ void msResetErrorList() { errorObj *ms_error, *this_error; ms_error = msGetErrorObj(); this_error = ms_error->next; while( this_error != NULL) { errorObj *next_error; next_error = this_error->next; msFree(this_error); this_error = next_error; } ms_error->next = NULL; ms_error->code = MS_NOERR; ms_error->routine[0] = '\0'; ms_error->message[0] = '\0'; /* -------------------------------------------------------------------- */ /* Cleanup our entry in the thread list. This is mainly */ /* imprortant when msCleanup() calls msResetErrorList(). */ /* -------------------------------------------------------------------- */ #ifdef USE_THREAD { int thread_id = msGetThreadId(); te_info_t *link; msAcquireLock( TLOCK_ERROROBJ ); /* find link for this thread */ for( link = error_list; link != NULL && link->thread_id != thread_id && link->next != NULL && link->next->thread_id != thread_id; link = link->next ) {} if( link->thread_id == thread_id ) { /* presumably link is at head of list. */ if( error_list == link ) error_list = link->next; free( link ); } else if( link->next != NULL && link->next->thread_id == thread_id ) { te_info_t *next_link = link->next; link->next = link->next->next; free( next_link ); } msReleaseLock( TLOCK_ERROROBJ ); } #endif }
static msIOContextGroup *msIO_GetContextGroup() { int nThreadId = msGetThreadId(); msIOContextGroup *prev = NULL, *group = io_context_list; if( group != NULL && group->thread_id == nThreadId ) return group; /* -------------------------------------------------------------------- */ /* Search for group for this thread */ /* -------------------------------------------------------------------- */ msAcquireLock( TLOCK_IOCONTEXT ); msIO_Initialize(); group = io_context_list; while( group != NULL && group->thread_id != nThreadId ) { prev = group; group = group->next; } /* -------------------------------------------------------------------- */ /* If we found it, make sure it is pushed to the front of the */ /* link for faster finding next time, and return it. */ /* -------------------------------------------------------------------- */ if( group != NULL ) { if( prev != NULL ) { prev->next = group->next; group->next = io_context_list; io_context_list = group; } msReleaseLock( TLOCK_IOCONTEXT ); return group; } /* -------------------------------------------------------------------- */ /* Create a new context group for this thread. */ /* -------------------------------------------------------------------- */ group = (msIOContextGroup *) calloc(sizeof(msIOContextGroup),1); group->stdin_context = default_contexts.stdin_context; group->stdout_context = default_contexts.stdout_context; group->stderr_context = default_contexts.stderr_context; group->thread_id = nThreadId; group->next = io_context_list; io_context_list = group; msReleaseLock( TLOCK_IOCONTEXT ); return group; }
errorObj *msGetErrorObj() { te_info_t *link; int thread_id; errorObj *ret_obj; msAcquireLock( TLOCK_ERROROBJ ); thread_id = msGetThreadId(); /* find link for this thread */ for( link = error_list; link != NULL && link->thread_id != thread_id && link->next != NULL && link->next->thread_id != thread_id; link = link->next ) {} /* If the target thread link is already at the head of the list were ok */ if( error_list != NULL && error_list->thread_id == thread_id ) { } /* We don't have one ... initialize one. */ else if( link == NULL || link->next == NULL ) { te_info_t *new_link; errorObj error_obj = { MS_NOERR, "", "", 0 }; new_link = (te_info_t *) malloc(sizeof(te_info_t)); new_link->next = error_list; new_link->thread_id = thread_id; new_link->ms_error = error_obj; error_list = new_link; } /* If the link is not already at the head of the list, promote it */ else if( link != NULL && link->next != NULL ) { te_info_t *target = link->next; link->next = link->next->next; target->next = error_list; error_list = target; } ret_obj = &(error_list->ms_error); msReleaseLock( TLOCK_ERROROBJ ); return ret_obj; }
/* returns MS_TRUE if the msIO standard output hasn't been redirected */ int msIO_isStdContext() { msIOContextGroup *group = io_context_list; int nThreadId = msGetThreadId(); if(!group || group->thread_id != nThreadId) { group = msIO_GetContextGroup(); if(!group) { return MS_FALSE; /* probably a bug */ } } if(group->stderr_context.cbData == (void*)stderr && group->stdin_context.cbData == (void*)stdin && group->stdout_context.cbData == (void*)stdout) return MS_TRUE; return MS_FALSE; }
msIOContext *msIO_getHandler( FILE * fp ) { int nThreadId = msGetThreadId(); msIOContextGroup *group = io_context_list; msIO_Initialize(); if( group == NULL || group->thread_id != nThreadId ) { group = msIO_GetContextGroup(); if( group == NULL ) return NULL; } if( fp == stdin || fp == NULL || strcmp((const char *)fp,"stdin") == 0 ) return &(group->stdin_context); else if( fp == stdout || strcmp((const char *)fp,"stdout") == 0 ) return &(group->stdout_context); else if( fp == stderr || strcmp((const char *)fp,"stderr") == 0 ) return &(group->stderr_context); else return NULL; }
void msConnPoolRegister( layerObj *layer, void *conn_handle, void (*close_func)( void * ) ) { const char *close_connection = NULL; connectionObj *conn = NULL; if( layer->debug ) msDebug( "msConnPoolRegister(%s,%s,%p)\n", layer->name, layer->connection, conn_handle ); /* -------------------------------------------------------------------- */ /* We can't meaningful keep a connection with no connection or */ /* connection type string on the layer. */ /* -------------------------------------------------------------------- */ if( layer->connection == NULL ) { if( layer->tileindex != NULL && layer->connectiontype == MS_OGR ) { /* this is ok, no need to make a fuss */ } else { msDebug( "%s: Missing CONNECTION on layer %s.\n", "msConnPoolRegister()", layer->name ); msSetError( MS_MISCERR, "Missing CONNECTION on layer %s.", "msConnPoolRegister()", layer->name ); } return; } /* -------------------------------------------------------------------- */ /* Grow the array of connection information objects if needed. */ /* -------------------------------------------------------------------- */ msAcquireLock( TLOCK_POOL ); if( connectionCount == connectionMax ) { connectionMax += 10; connections = (connectionObj *) realloc(connections, sizeof(connectionObj) * connectionMax ); if( connections == NULL ) { msSetError(MS_MEMERR, NULL, "msConnPoolRegister()"); msReleaseLock( TLOCK_POOL ); return; } } /* -------------------------------------------------------------------- */ /* Set the new connection information. */ /* -------------------------------------------------------------------- */ conn = connections + connectionCount; connectionCount++; conn->connectiontype = layer->connectiontype; conn->connection = msStrdup( layer->connection ); conn->close = close_func; conn->ref_count = 1; conn->thread_id = msGetThreadId(); conn->last_used = time(NULL); conn->conn_handle = conn_handle; conn->debug = layer->debug; /* -------------------------------------------------------------------- */ /* Categorize the connection handling information. */ /* -------------------------------------------------------------------- */ close_connection = msLayerGetProcessingKey( layer, "CLOSE_CONNECTION" ); if( close_connection == NULL ) close_connection = "NORMAL"; if( strcasecmp(close_connection,"NORMAL") == 0 ) conn->lifespan = MS_LIFE_ZEROREF; else if( strcasecmp(close_connection,"DEFER") == 0 ) conn->lifespan = MS_LIFE_FOREVER; else if( strcasecmp(close_connection,"ALWAYS") == 0 ) conn->lifespan = MS_LIFE_SINGLE; else { msDebug("msConnPoolRegister(): " "Unrecognised CLOSE_CONNECTION value '%s'\n", close_connection ); msSetError( MS_MISCERR, "Unrecognised CLOSE_CONNECTION value '%s'", "msConnPoolRegister()", close_connection ); conn->lifespan = MS_LIFE_ZEROREF; } msReleaseLock( TLOCK_POOL ); }