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

📄 o_timeout.c,v

📁 这是P2P流媒体方案-NICE的实现源码
💻 C,V
字号:
head	1.1;access;symbols;locks; strict;comment	@ * @;1.1date	2002.07.02.19.30.05;	author rbraud;	state Exp;branches;next	;desc@@1.1log@Initial revision@text@/* * timeout.c -- aux routines for timeouts. * * PURIFY FIX:  Many things. *  - It was possible for timeout structure blocks to be reallocated without *    being freed first.  Fixed this. *  - Signals were not being block consistantly.  I made it so that signals *    are only blocking in the entry-point functions, and not in all of the *    utility functions. *  - It was possible for a timer to expire in this code just after the timer *    was canceled in hwt.c  *  - Got rid of unused functions and commented out code for clarity. *  - Made the code easier to read. */#include <signal.h>#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include "general.h"#include "util.h"#include "utilDebug.h"//#include "sys/o_threads.h"#include "o_timeout.h"#define NTOPERBLK	500#define MAXTOBLK	60static timeout_t       *timeouts[MAXTOBLK];static timeout_t       *pending_timeouts;static int             timeout_hw = 0;static int             num_blocks = 0;static int             beating    = 0;//static o_thread_mutex  to_mutex;//static o_thread_mutex  pt_mutex;//static o_thread_mutex  hb_mutex;static sigset_t        timer_mask;static sigset_t        orig_mask;static int mask_set = FALSE;  // To ensure that the mask is set only once./*==========================================================================*/void UTIL_check(int cond, char *msg){  /*   * Check condition "cond", exit if zero.   */  if (!cond)  {    fprintf(stderr, "Fatal error in File %s at line %d: %s\n",            __FILE__, __LINE__, msg);    exit(3);  }}/*==========================================================================*/void init_timer_mask(){  sigemptyset(&timer_mask);  sigemptyset(&orig_mask);  sigaddset(&timer_mask, SIGALRM);  sigprocmask(0x0, 0x0, &orig_mask);  /* Get the current mask. */}/*==========================================================================*/int mask_timer(void){  if(mask_set == FALSE) {    mask_set = TRUE;    sigprocmask(SIG_BLOCK, &timer_mask, &orig_mask);     //  pthread_sigmask(SIG_BLOCK, &timer_mask, &orig_mask);    return CALL_UNMASK_TIMER;  } else return DONT_CALL_UNMASK_TIMER;}/*==========================================================================*/void unmask_timer(void){   sigprocmask(SIG_SETMASK, &orig_mask, 0x0);   //  pthread_sigmask(SIG_SETMASK, &orig_mask, 0x0);  mask_set = FALSE; }/*==========================================================================*/timeout_t *alloc_timeout(){  timeout_t  *tp;  int        nblk;  int        i;  int        j;    /*   * Get a new timeout structure.  This function should never return NULL.   */  nblk = (timeout_hw / NTOPERBLK);    //  o_thr_mutex_lock(&to_mutex);    while (nblk >= num_blocks)  {        /*     * Time to allocate more timeout structures.     */    UTIL_check((num_blocks < MAXTOBLK), "Too many Timeouts!");        timeouts[num_blocks] = (timeout_t *)calloc(NTOPERBLK, sizeof(timeout_t));    num_blocks++;  }    /*   * Do a linear search for a free timeout structure.   */  for (i = 0; i <= nblk; i++)  {    tp = timeouts[i];        for (j = 0; j < NTOPERBLK; j++)    {      if (tp->to_busy == 0)      {        tp->to_next = NULL;        tp->to_prev = NULL;        tp->to_busy = 1;                timeout_hw++;        	//        o_thr_mutex_unlock(&to_mutex);        return(tp);      }            tp++;    }  }    //  o_thr_mutex_unlock(&to_mutex);  UTIL_check(0, "Didn't find a free timeout!");  return(NULL);}/*==========================================================================*/void free_timeout_unprot(timeoutHandle_t tp){  UTIL_check((tp != NULL), "Tried to free a NULL timeout.");    /*   * Set the busy flag to 0 and decrement the number of timeout structures   * currently allocated.   */  tp->to_busy = 0;  timeout_hw--;}/*==========================================================================*/void free_timeout(timeoutHandle_t tp){    /*   * Get the to mutex lock, then free it.   */  //  o_thr_mutex_lock(&to_mutex);    free_timeout_unprot(tp);    //  o_thr_mutex_unlock(&to_mutex);}/*==========================================================================*/void _heartbeat(int a){  timeout_t  *tp;    /*   * Attempt to get all of the locks.  If we cannot get any of the locks, then   * return so as to not hold up the timer.  Note that SIGALRM is   * automatically blocked due to the use of ualarm() and the sa_mask   * specified in sigaction().   */  /*  if (o_thr_mutex_trylock(&hb_mutex) != 0)  {    return;  }    if (o_thr_mutex_trylock(&pt_mutex) != 0)  {    o_thr_mutex_unlock(&hb_mutex);    return;  }    if (o_thr_mutex_trylock(&to_mutex) != 0)  {    o_thr_mutex_unlock(&hb_mutex);    o_thr_mutex_unlock(&pt_mutex);    return;  }  */  /*   * Handle callouts, if any.   */  if (pending_timeouts != NULL)  {    pending_timeouts->to_ticks -= 1;  /* Another tick of the clock. */        while ((pending_timeouts != NULL) &&           (pending_timeouts->to_ticks == 0))    {            /*       * Some have expired.       */      tp = pending_timeouts;            /*       * Take tp out of the pending timeouts linked list and reset       * pending_timeouts.       */      if (tp->to_next != NULL)      {        tp->to_next->to_prev = NULL;      }            pending_timeouts = tp->to_next;            /*       * Perform the callback, unlocking the pt and to mutexes to allow the       * callback funstion to set and cancel timers.       */      //      o_thr_mutex_unlock(&to_mutex);      //      o_thr_mutex_unlock(&pt_mutex);            (tp->to_fun)(tp->to_arg1);            //      o_thr_mutex_lock(&pt_mutex);      //      o_thr_mutex_lock(&to_mutex);            /*       * Free the expired timeout.       */      free_timeout_unprot(tp);    }  }    //  o_thr_mutex_unlock(&to_mutex);   //  o_thr_mutex_unlock(&pt_mutex);  //  o_thr_mutex_unlock(&hb_mutex);}/*==========================================================================*/void start_heartbeat(){  struct sigaction  act;    /*   * Only start the heartbeat once.   */  if (!beating)  {    #ifdef THREADED    UTIL_check(0, "Please update the starthb() routine.");#else        act.sa_handler   = _heartbeat;    act.sa_flags     = 0;    act.sa_flags    |= SA_RESTART;    #ifdef linux    act.sa_handler   = _heartbeat;#endif    #ifdef solaris2    act.sa_sigaction = _heartbeat;#endif        sigemptyset(&act.sa_mask);        sigaddset(&act.sa_mask, SIGPOLL);       sigaddset(&act.sa_mask, SIGALRM);        sigaction(SIGALRM, &act, 0x0);        UTIL_check(((long)ualarm(USEC_PER_TICK, USEC_PER_TICK) != -1L),                 "Unable to start interval alarm.");    #endif        beating++;  }}/*==========================================================================*/void enqueue_timeout(timeoutHandle_t p){  timeout_t  *pp;  timeout_t  *lp;  int        pval;    /*   * Add p to the pending_timeouts list.   */    if (p == NULL)  {    //    UTIL_InfoMessage(UTIL_ERROR, "enqueue_timeout called with null timeout");    return;  }    //  o_thr_mutex_lock(&pt_mutex);    if ((pp = pending_timeouts) == NULL)  {    pending_timeouts = p;    //    o_thr_mutex_unlock(&pt_mutex);    return;  }    /*   * p and pp are non-NULL.  Something is currently on the list.  Find the   * first entry to expire AFTER the new one.   */  lp   = NULL;  pval = p->to_ticks;    while ((pval > pp->to_ticks) && (pp->to_next != NULL))  {    /*     * Both (pp != NULL) and (pp->to_next != NULL).     */    lp    = pp;    pval -= pp->to_ticks;    pp    = pp->to_next;  }    /*   * Either (pval <= pp->to_ticks) or (pp->to_next == NULL).   */  if (pval > pp->to_ticks)  {    /*     * New entry is the last in the list.     */    pval       -= pp->to_ticks;  /* One more decrement. */    p->to_ticks = pval;    p->to_prev  = pp;    p->to_next  = NULL;    pp->to_next = p;        //    o_thr_mutex_unlock(&pt_mutex);    return;  }    /*   * New entry is not the last in the list.   */  p->to_next    = pp;  p->to_prev    = lp;  p->to_ticks   = pval;  pp->to_ticks -= pval;  /* Decrement the rest of the values. */  pp->to_prev   = p;    if (lp == NULL)  {    pending_timeouts = p;  }  else  {    lp->to_next = p;  }    //  o_thr_mutex_unlock(&pt_mutex);  return;}/*==========================================================================*/void initTimeout(){  /*   * Set up the timeout code and data.   */  pending_timeouts = NULL;  /* Set the debug file pointer for UTIL_XXX functions to be "stderr" */  //  UTIL_SetDebugFile(stderr);    //  o_thr_mutex_init(&to_mutex, NULL);  //  o_thr_mutex_init(&pt_mutex, NULL);  //  o_thr_mutex_init(&hb_mutex, NULL);    init_timer_mask();    start_heartbeat();}/*==========================================================================*/timeoutHandle_t startTimer(int t, void (*func)(int), int arg1, int arg2){  timeout_t  *tp;  //int call_unmask_timer;   /*   * Arrange for func to be called with argument arg in t "ticks".   */    UTIL_check(beating, "StartTimer called before initTimeout.");    UTIL_check((t > 0), "StartTimer called with nonpositive arg.");    //call_unmask_timer = mask_timer();    tp = alloc_timeout();    tp->to_ticks = t;  tp->to_fun   = func;  tp->to_arg1  = arg1;  tp->to_arg2  = arg2;    enqueue_timeout(tp);    //if(call_unmask_timer == CALL_UNMASK_TIMER)  //  unmask_timer();  return(tp);}/*==========================================================================*/int cancelTimer(timeoutHandle_t tim){  /*   * Return val:  0 == OK   *             -1 == Never heard of it   */   //int call_unmask_timer;   if (tim == NULL)  {    return(1);  }    //call_unmask_timer = mask_timer();  //  o_thr_mutex_lock(&to_mutex);    if (tim->to_busy == 0)  {    //    o_thr_mutex_unlock(&to_mutex);  //  if(call_unmask_timer == CALL_UNMASK_TIMER)  //    unmask_timer();    return(-1);  }    //  o_thr_mutex_unlock(&to_mutex);  //  o_thr_mutex_lock(&pt_mutex);    if (tim->to_next != NULL)  {    /*     * There is a next timeout entry.     */    tim->to_next->to_prev   = tim->to_prev;    tim->to_next->to_ticks += tim->to_ticks;   /* Add time to next entry. */  }    if (tim->to_prev != NULL)  {    /*     * Not the first element.     */    tim->to_prev->to_next = tim->to_next;  }  else  {    /*     * First in the list.     */    pending_timeouts = tim->to_next;  }    //  o_thr_mutex_unlock(&pt_mutex);    free_timeout(tim);  //if(call_unmask_timer == CALL_UNMASK_TIMER)    //  unmask_timer();  return(0);}@

⌨️ 快捷键说明

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