Example #1
0
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;
}
Example #2
0
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));
    }
}
Example #3
0
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;
}
Example #4
0
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());
}
Example #5
0
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));
}
Example #6
0
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));
}
Example #7
0
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;
}
Example #8
0
/**
 * 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();
}
Example #9
0
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);
}