⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cron.c

📁 GNUnet是一个安全的点对点网络框架
💻 C
📖 第 1 页 / 共 2 页
字号:
/*     This file is part of GNUnet.     (C) 2001, 2002, 2003, 2004, 2005, 2006 Christian Grothoff (and other contributing authors)     GNUnet is free software; you can redistribute it and/or modify     it under the terms of the GNU General Public License as published     by the Free Software Foundation; either version 2, or (at your     option) any later version.     GNUnet is distributed in the hope that it will be useful, but     WITHOUT ANY WARRANTY; without even the implied warranty of     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     General Public License for more details.     You should have received a copy of the GNU General Public License     along with GNUnet; see the file COPYING.  If not, write to the     Free Software Foundation, Inc., 59 Temple Place - Suite 330,     Boston, MA 02111-1307, USA.*//** * @file util/pthreads/cron.c * @author Christian Grothoff * @brief Module for periodic background (cron) jobs. * * The module only uses one thread, thus every cron-job must be * short-lived, should never block for an indefinite amount of * time. Specified deadlines are only a guide-line, the 10ms * timer-resolution is only an upper-bound on the possible precision, * in practice it will be worse (depending on the other cron-jobs). * * If you need to schedule a long-running or blocking cron-job, * run a function that will start another thread that will * then run the actual job. */#include "gnunet_util.h"#include "gnunet_util_cron.h"#include "platform.h"#define DEBUG_CRON GNUNET_NO#if DEBUG_CRON#define HAVE_PRINT_CRON_TAB 1#else#define HAVE_PRINT_CRON_TAB 0#endif/** * The initial size of the cron-job table */#define INIT_CRON_JOBS 16/** * how long do we sleep at most? In some systems, the * signal-interrupted sleep does not work nicely, so to ensure * progress, we should rather wake up periodically. (But we don't want * to burn too much CPU time doing busy waiting; every 2s strikes a * good balance) */#define MAXSLEEP 2000#define CHECK_ASSERTS 1/* change this value to artificially speed up all   GNUnet cron timers by this factor. E.g. with 10,   a cron-job scheduled after 1 minute in the code   will occur after 6 seconds. This is useful for   testing bugs that would otherwise occur only after   a long time.   For releases, this value should always be 1 */#define SPEED_UP 1/** number of cron units (ms) in a second */#define CRON_UNIT_TO_SECONDS (1000 / SPEED_UP)/** number of us [usec] in a cron-unit (1000) */#define MICROSEC_TO_CRON_UNIT (1000 * SPEED_UP)/** * @brief The Delta-list for the cron jobs. */typedef struct{  /**   * The method to call at that point.   */  GNUNET_CronJob method;  /**   * data ptr (argument to the method)   */  void *data;  /**   * The start-time for this event (in milliseconds).   */  GNUNET_CronTime delta;  /**   * for cron-jobs: when this should be repeated   * automatically, 0 if this was a once-only job   */  unsigned int deltaRepeat;  /**   * The index of the next entry in the delta list   * after this one (-1 for none)   */  int next;} UTIL_cron_DeltaListEntry;typedef struct GNUNET_CronManager{  /**   * The lock for the delta-list.   */  struct GNUNET_Mutex *deltaListLock_;  /**   * The delta-list of waiting tasks.   */  UTIL_cron_DeltaListEntry *deltaList_;  /**   * The currently running job.   */  GNUNET_CronJob runningJob_;  void *runningData_;  struct GNUNET_GE_Context *ectx;  /**   * The cron thread.   */  struct GNUNET_ThreadHandle *cron_handle;  struct GNUNET_Semaphore *cron_signal;  struct GNUNET_Semaphore *cron_signal_up;  struct GNUNET_Mutex *inBlockLock_;  unsigned int runningRepeat_;  /**   * The current size of the DeltaList.   */  unsigned int deltaListSize_;  /**   * The first empty slot in the delta-list.   */  int firstFree_;  /**   * The first empty slot in the delta-list.   */  int firstUsed_;  /**   * Set to yes if we are shutting down or shut down.   */  int cron_shutdown;  /**   * Are we in block?   */  int inBlock;  struct GNUNET_Semaphore *sig;} CronManager;struct GNUNET_CronManager *GNUNET_cron_create (struct GNUNET_GE_Context *ectx){  struct GNUNET_CronManager *cron;  unsigned int i;  cron = GNUNET_malloc (sizeof (CronManager));  memset (cron, 0, sizeof (CronManager));  cron->deltaListSize_ = INIT_CRON_JOBS;  cron->deltaList_    =    GNUNET_malloc (sizeof (UTIL_cron_DeltaListEntry) * cron->deltaListSize_);  for (i = 0; i < cron->deltaListSize_; i++)    cron->deltaList_[i].next = i - 1;  cron->firstFree_ = cron->deltaListSize_ - 1;  cron->deltaListLock_ = GNUNET_mutex_create (GNUNET_YES);  cron->inBlockLock_ = GNUNET_mutex_create (GNUNET_NO);  cron->runningJob_ = NULL;  cron->firstUsed_ = -1;  cron->cron_signal_up = GNUNET_semaphore_create (0);  cron->ectx = ectx;  cron->cron_shutdown = GNUNET_YES;  cron->sig = NULL;  return cron;}static voidnoJob (void *unused){#if DEBUG_CRON  GNUNET_GE_LOG (NULL,                 GNUNET_GE_STATUS | GNUNET_GE_DEVELOPER | GNUNET_GE_BULK,                 "In noJob.\n");#endif}voidGNUNET_cron_stop (struct GNUNET_CronManager *cron){  void *unused;#if DEBUG_CRON  GNUNET_GE_LOG (cron->ectx,                 GNUNET_GE_STATUS | GNUNET_GE_DEVELOPER | GNUNET_GE_BULK,                 "Stopping cron\n");#endif  cron->cron_shutdown = GNUNET_YES;  GNUNET_cron_add_job (cron, &noJob, 0, 0, NULL);  GNUNET_semaphore_down (cron->cron_signal, GNUNET_YES);  GNUNET_semaphore_destroy (cron->cron_signal);  cron->cron_signal = NULL;  GNUNET_thread_join (cron->cron_handle, &unused);#if DEBUG_CRON  GNUNET_GE_LOG (NULL,                 GNUNET_GE_STATUS | GNUNET_GE_DEVELOPER | GNUNET_GE_BULK,                 "Cron stopped\n");#endif}/** * GNUNET_CronJob to suspend the cron thread * until it is resumed. */static voidblock (void *cls){  struct GNUNET_CronManager *cron = cls;  int ok = GNUNET_SYSERR;  if (cron->sig != NULL)    GNUNET_semaphore_up (cron->sig);  while (ok == GNUNET_SYSERR)    {      GNUNET_semaphore_down (cron->cron_signal_up, GNUNET_YES);      GNUNET_mutex_lock (cron->inBlockLock_);      cron->inBlock--;      if (cron->inBlock == 0)        ok = GNUNET_OK;      GNUNET_mutex_unlock (cron->inBlockLock_);    }}voidGNUNET_cron_suspend_jobs (struct GNUNET_CronManager *cron, int checkSelf){  if ((GNUNET_YES == checkSelf) &&      (cron->cron_shutdown == GNUNET_NO) &&      (GNUNET_NO != GNUNET_thread_test_self (cron->cron_handle)))    return;  GNUNET_GE_ASSERT (NULL,                    GNUNET_NO == GNUNET_thread_test_self (cron->cron_handle));  GNUNET_mutex_lock (cron->inBlockLock_);  cron->inBlock++;  if (cron->inBlock == 1)    {      cron->sig = GNUNET_semaphore_create (0);      GNUNET_cron_add_job (cron, &block, 0, 0, cron);      GNUNET_semaphore_down (cron->sig, GNUNET_YES);      GNUNET_semaphore_destroy (cron->sig);      cron->sig = NULL;    }  GNUNET_mutex_unlock (cron->inBlockLock_);}intGNUNET_cron_test_running (struct GNUNET_CronManager *cron){  if ((GNUNET_NO == cron->cron_shutdown) || (cron->inBlock > 0))    return GNUNET_YES;  else    return GNUNET_NO;}voidGNUNET_cron_resume_jobs (struct GNUNET_CronManager *cron, int checkSelf){  if ((GNUNET_YES == checkSelf) &&      (cron->cron_shutdown == GNUNET_NO) &&      (GNUNET_NO != GNUNET_thread_test_self (cron->cron_handle)))    return;  GNUNET_GE_ASSERT (NULL, cron->inBlock > 0);  GNUNET_semaphore_up (cron->cron_signal_up);}static voidabortSleep (struct GNUNET_CronManager *cron){  if (cron->cron_signal == NULL)    return;                     /* cron_handle not valid */  GNUNET_thread_stop_sleep (cron->cron_handle);}#if HAVE_PRINT_CRON_TAB/** * Print the cron-tab. */voidprintCronTab (struct GNUNET_CronManager *cron){  int jobId;  UTIL_cron_DeltaListEntry *tab;  GNUNET_CronTime now;  now = GNUNET_get_time ();  GNUNET_mutex_lock (cron->deltaListLock_);  jobId = cron->firstUsed_;  while (jobId != -1)    {      tab = &cron->deltaList_[jobId];      GNUNET_GE_LOG (NULL,                     GNUNET_GE_STATUS | GNUNET_GE_DEVELOPER | GNUNET_GE_BULK,                     "%3u: delta %8lld CU --- method %p --- repeat %8u CU\n",                     jobId, tab->delta - now, (int) tab->method,                     tab->deltaRepeat);      jobId = tab->next;    }  GNUNET_mutex_unlock (cron->deltaListLock_);}#endifvoidGNUNET_cron_advance_job (struct GNUNET_CronManager *cron,                         GNUNET_CronJob method, unsigned int deltaRepeat,                         void *data){  UTIL_cron_DeltaListEntry *job;  UTIL_cron_DeltaListEntry *last;  int jobId;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -