void * SqlPool::monitor_thread() { block_sigpipe(); LOG(ll_INFO, _T("monitor thread started")); while (sleep_not_stop()) { // processing 'idle close' ScopedLock lock(pool_mux_); std::map<String, Pool>::iterator i = pools_.begin(), iend = pools_.end(); for (bool quit = false; !quit && i != iend; ++i) { Pool::iterator j = i->second.begin(), jend = i->second.end(); for (; j != jend; ++j) { if (time(NULL) - (*j)->free_since_ >= idle_time_) { quit = true; String del_source_id = i->first; SqlConnectionPtr del_handle = *j; int del_count = counts_[del_source_id]; i->second.erase(j); int del_pool_sz = i->second.size(); LOG(ll_DEBUG, _T("closing idle connection") + format_stats(del_source_id)); delete del_handle; LOG(ll_INFO, _T("closed idle connection") + format_stats(del_source_id, del_count, del_pool_sz)); break; } } } } return NULL; }
void SqlPool::put(SqlConnectionPtr handle, bool close_now) { if (!handle) return; if (handle->bad()) close_now = true; if (!close_now) handle->clear(); if (handle->bad()) close_now = true; const String source_id = handle->get_source().id(); ScopedLock lock(pool_mux_); --counts_[source_id]; if (!close_now) { handle->free_since_ = time(NULL); pools_[source_id].push_back(handle); LOG(ll_INFO, _T("put connection") + get_stats(source_id)); } else { LOG(ll_DEBUG, _T("forced closing connection") + format_stats(source_id)); delete handle; LOG(ll_INFO, _T("forced closed connection") + get_stats(source_id)); } }
SqlPool::SqlConnectionPtr SqlPool::get(const String &source_id, int timeout) { SqlSource src; { ScopedLock lock(pool_mux_); std::map<String, SqlSource>::iterator source_it = sources_.find(source_id); if (sources_.end() == source_it) throw PoolError(_T("Unknown source ID: ") + source_id); if (pools_[source_id].size()) { SqlConnectionPtr handle = pools_[source_id].front(); ++counts_[source_id]; pools_[source_id].pop_front(); LOG(ll_INFO, _T("got connection") + get_stats(source_id)); return handle; } src = source_it->second; } LOG(ll_DEBUG, _T("opening connection") + format_stats(source_id)); SqlConnectionPtr handle; if (interlocked_open_) { ScopedLock lock(open_mux_); handle = new SqlConnection(src); } else handle = new SqlConnection(src); LOG(ll_INFO, _T("opened connection") + get_stats(source_id)); { ScopedLock lock(pool_mux_); ++counts_[source_id]; } return handle; }
const String SqlPool::get_stats(const String &source_id) { std::map<String, int>::iterator c = counts_.find(source_id); if (counts_.end() == c) return _T(" [source: ") + source_id + _T(", unknown source]"); return format_stats(source_id, c->second, pools_[source_id].size()); }
static void set_attacker_info(twindow& window, const unit& u) { set_label<timage>(window, "attacker_image", u.absolute_image() + get_image_mods(u)); tcontrol& attacker_name = find_widget<tcontrol>(&window, "attacker_stats", false); attacker_name.set_use_markup(true); attacker_name.set_label(format_stats(u)); }
static void set_defender_info(twindow& window, const unit& u) { // Ensure the defender image is always facing left set_label<timage>(window, "defender_image", u.absolute_image() + "~FL(horiz)" + get_image_mods(u)); tcontrol& defender_name = find_widget<tcontrol>(&window, "defender_stats", false); defender_name.set_use_markup(true); defender_name.set_label(format_stats(u)); }
bool SqlPool::reconnect(SqlConnectionPtr &conn) { const SqlSource source = conn->get_source(); const String &source_id = source.id(); put(conn, true); // close now LOG(ll_DEBUG, _T("reopening connection") + format_stats(source_id)); ScopedLock lock(pool_mux_); conn = new SqlConnection(source); ++counts_[source_id]; LOG(ll_INFO, _T("reopened connection") + get_stats(source_id)); return true; }
/** * Prints LIBCx version and memory usage statistics to stdout. */ void print_stats() { int rc; _HEAPSTATS hst; printf("LIBCx version: " VERSION_MAJ_MIN_BLD LIBCX_DEBUG_SUFFIX LIBCX_DEV_SUFFIX "\n"); { char name[CCHMAXPATH] = {0}; get_module_name(name, sizeof(name)); printf("LIBCx module: %s\n", name); } global_lock(); char buf[StatsBufSize]; format_stats(buf, sizeof(buf)); fputs(buf, stdout); global_unlock(); }
static void shared_term() { APIRET arc; int rc; TRACE("gMutex %lx, gpData %p (heap %p, refcnt %d), gSeenAssertion %lu\n", gMutex, gpData, gpData ? gpData->heap : 0, gpData ? gpData->refcnt : 0, gSeenAssertion); #if !defined(TRACE_ENABLED) if (gSeenAssertion && get_log_instance()) { /* * We're crashing after an assertion, write out LIBCx stats (not needed in * trace builds as we will trace that out later anyway) */ char *buf = alloca(StatsBufSize); if (buf) { format_stats(buf, StatsBufSize); __libc_LogRaw(gLogInstance, __LIBC_LOG_MSGF_FLUSH, buf, StatsBufSize); } } #endif ASSERT(gSeenAssertion || gMutex != NULLHANDLE); DosRequestMutexSem(gMutex, SEM_INDEFINITE_WAIT); if (gpData) { if (gpData->heap) { int i; ProcDesc *proc; ASSERT(gpData->refcnt); gpData->refcnt--; /* Remove the process description upon process termination */ size_t bucket = 0; ProcDesc *prev = NULL; proc = find_proc_desc_ex(getpid(), &bucket, &prev); /* Uninitialize individual components */ fcntl_locking_term(proc); mmap_term(proc); TRACE("proc %p\n", proc); if (proc) { if (proc->spawn2_wrappers) { TRACE("proc->spawn2_wrappers %p\n", proc->spawn2_wrappers); free(proc->spawn2_wrappers); } if (proc->spawn2_sem) { TRACE("proc->spawn2_sem %lx (refcnt %d)\n", proc->spawn2_sem, gpData->spawn2_sem_refcnt); ASSERT(proc->spawn2_sem == gpData->spawn2_sem); DosCloseEventSem(gpData->spawn2_sem); ASSERT(gpData->spawn2_sem_refcnt != 0); --gpData->spawn2_sem_refcnt; if (gpData->spawn2_sem_refcnt == 0) gpData->spawn2_sem = NULLHANDLE; } /* Free common per-process structures */ TRACE("proc->files %p\n", proc->files); if (proc->files) { for (i = 0; i < FILE_DESC_HASH_SIZE; ++i) { FileDesc *desc = proc->files[i]; while (desc) { FileDesc *next = desc->next; free_file_desc(desc, i, NULL, NULL); desc = next; } } free(proc->files); } free_proc_desc(proc, bucket, prev); } if (gpData->refcnt == 0) { /* We are the last process, free common structures */ TRACE("gpData->files %p\n", gpData->files); if (gpData->files) { /* Make sure we don't have lost SharedFileDesc data */ for (i = 0; i < FILE_DESC_HASH_SIZE; ++i) ASSERT_MSG(!gpData->files[i], "%p", gpData->files[i]); free(gpData->files); } TRACE("gpData->procs %p\n", gpData->procs); if (gpData->procs) free(gpData->procs); } #ifdef TRACE_ENABLED { char *buf = alloca(StatsBufSize); if (buf) { format_stats(buf, StatsBufSize); TRACE("%s", buf); } } #endif _uclose(gpData->heap); if (gpData->refcnt == 0) { #ifdef STATS_ENABLED _HEAPSTATS hst; rc = _ustats(gpData->heap, &hst); ASSERT_MSG(!rc, "%d (%d)", rc, errno); ASSERT_MSG(!hst._used, "%d", hst._used); #endif rc = _udestroy(gpData->heap, !_FORCE); TRACE("_udestroy = %d (%d)\n", rc, errno); } } arc = DosFreeMem(gpData); TRACE("DosFreeMem = %ld\n", arc); } DosReleaseMutexSem(gMutex); arc = DosCloseMutexSem(gMutex); if (arc == ERROR_SEM_BUSY) { /* The semaphore may be owned by us, try to release it */ arc = DosReleaseMutexSem(gMutex); TRACE("DosReleaseMutexSem = %ld\n", arc); arc = DosCloseMutexSem(gMutex); } TRACE("DosCloseMutexSem = %ld\n", arc); DosExitList(EXLST_REMOVE, ProcessExit); }