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

📄 garbage.c

📁 IBM的Linux上的PKCS#11实现
💻 C
📖 第 1 页 / 共 2 页
字号:
  Slot_Mgr_Shr_t               *MemPtr              = (Slot_Mgr_Shr_t *) Ptr;  void *Status;  if ( ! ThreadRunning ) {    DbgLog(DL0,"StopGCThread was called when the garbage collection thread was not running");    return FALSE;  }  DbgLog(DL0, "StopGCThread: tid %d is stopping the garbage collection thread (tid %d)", pthread_self(), GCThread);  /* Cause the GC thread to be cancelled */  if ( ( err = pthread_cancel(GCThread)) != 0 ) {    DbgLog(DL0,"StopGCThread: pthread_cancel returned %s (%d; %#x)", SysConst(err), err, err );    return FALSE;  }  /* Synchronize with the GC thread (aka: wait for it to terminate) */  if ( (err = pthread_join ( GCThread, &Status ) ) != 0 ) {    DbgLog(DL0,"StopGCThread: pthread_join returned %s (%d; %#x)", SysConst(err), err, err );    return FALSE;  }  if ( Status != PTHREAD_CANCELED ) {    DbgLog(DL0,"Hmm.  Thread was cancelled, but didn't return the appropriate return status");  }  ThreadRunning = FALSE;  return TRUE;}/********************************************************************************* * GCMain - *  *     The Garbage collection thread's main() *     Basically, run until cancelled by another thread *  *********************************************************************************/static void *GCMain ( void *Ptr) {  int                           OrigCancelState;  int                           OrigCancelType;  int                           LastCancelState;  int                           i;  Slot_Mgr_Shr_t               *MemPtr              = (Slot_Mgr_Shr_t *) Ptr;    ASSERT ( MemPtr != NULL );  /* setup */  /* Block the signals that go to the main thread */  /* FIXME: We probably want to make it so that signals go only to the main thread by default */  GCBlockSignals();  /* Make it so that we can only be cancelled when we reach a cancellation point */  /* cancellation points are listed here: http://techlib.austin.ibm.com/techlib/manuals/adoclib/aixprggd/genprogc/termthre.htm#D3A4499176manu */  /* PTHREAD_CANCEL_DEFERRED should be the default */  pthread_setcancelstate ( PTHREAD_CANCEL_ENABLE,  &OrigCancelState );  pthread_setcanceltype  ( PTHREAD_CANCEL_DEFERRED, &OrigCancelType  );  /* push cleanup routines */  pthread_cleanup_push ( GCCancel, MemPtr );  while ( 1 ) {    DbgLog(DL5, "Garbage collection running...");    /* Don't allow cancellations while mucking with shared memory or holding mutexes */    pthread_setcancelstate ( PTHREAD_CANCEL_DISABLE, &LastCancelState );    CheckForGarbage(MemPtr);    /* re-enable cancellations */    pthread_setcancelstate ( PTHREAD_CANCEL_ENABLE, &LastCancelState );    /* Test for cancellation by the main thread */    pthread_testcancel();    DbgLog(DL5, "Garbage collection finished.");    /* now we pause */    sleep(10);  } /* end while 1 */  /* Yeah, yeah.  Has to be here because some implementations use macros that have to be balanced */  pthread_cleanup_pop ( 0 );  /* return implicitly calls pthread_cancel() */  /* but it'll never really get executed; pthread_testcancel() implicitly calls pthread_exit() if there's a cancellation pending */  return NULL;}/********************************************************************************* * GCCancel -  *  *       Cleanup routine called when Garbage collection thread exits/is cancelled *  *********************************************************************************/static void GCCancel ( void *Ptr ) {  Slot_Mgr_Shr_t               *MemPtr              = (Slot_Mgr_Shr_t *) Ptr;  /* Yeah, yeah.  Doesn't do anything, but I had plans */  DbgLog(DL3, "GCCancel: tid: %d running cleanup routine", pthread_self());  return;}/********************************************************************************* * CheckForGarbage - *  *       The routine that actually does cleanup *  *********************************************************************************/BOOL CheckForGarbage ( Slot_Mgr_Shr_t *MemPtr ) {  int               SlotIndex;  int               ProcIndex;  int               Err;  BOOL              ValidPid;  ASSERT( MemPtr != NULL_PTR );  #ifdef DEV    DbgLog(DL5, "Thread %d is checking for garbage", pthread_self());  #endif /* DEV */  #ifdef DEV    DbgLog (DL5, "Garbage collection attempting global shared memory lock");  #endif /* DEV */  /* Grab the global Shared mem mutex since we might modify global_session_count */#ifdef PKCS64  Err = msem_lock(&(MemPtr->slt_mutex),0);#else  Err = pthread_mutex_lock ( &(MemPtr->slt_mutex) );#endif  if ( Err != 0 ) {    DbgLog (DL0, "Garbage collection: Locking attempt for global shmem mutex returned %s", SysConst(Err) );    return FALSE;  }  #ifdef DEV  DbgLog ( DL5, "Garbage collection: Got global shared memory lock");  #endif /* DEV */  for ( ProcIndex = 0; ProcIndex < NUMBER_PROCESSES_ALLOWED; ProcIndex++ ) {#ifdef PKCS64    Slot_Mgr_Proc_t_64 *pProc = &(MemPtr->proc_table[ProcIndex]);#else    Slot_Mgr_Proc_t   *pProc = &(MemPtr->proc_table[ProcIndex]);#endif    ASSERT(pProc != NULL_PTR);    if ( ! (pProc->inuse) ) {      continue;    }    ValidPid = ( (IsValidProcessEntry ( pProc->proc_id, pProc->reg_time )) && (pProc->proc_id != 0) );    if ( ( pProc->inuse ) && (! ValidPid ) ) {      #ifdef DEV        DbgLog(DL1, "Garbage collection routine found bad entry for pid %d (Index: %d); removing from table", pProc->proc_id, ProcIndex );      #endif /* DEV */      /*                         */      /* Clean up session counts */      /*                         */      for ( SlotIndex = 0; SlotIndex < NUMBER_SLOTS_MANAGED; SlotIndex++ ) {#ifdef PKCS64	unsigned int *pGlobalSessions    = &(MemPtr->slot_info[SlotIndex].global_sessions);	unsigned int *pProcSessions      = &(pProc->slot_session_count[SlotIndex]);#else	int *pGlobalSessions    = &(MemPtr->slot_info[SlotIndex].global_sessions);	int *pProcSessions      = &(pProc->slot_session_count[SlotIndex]);#endif	if ( *pProcSessions > 0 ) {  	  #ifdef DEV	    DbgLog ( DL2, "GC: Invalid pid (%d) is holding %d sessions open on slot %d.  Global session count for this slot is %d", pProc->proc_id, *pProcSessions, SlotIndex, *pGlobalSessions );          #endif /* DEV */	  if ( *pProcSessions > *pGlobalSessions ) {	    #ifdef DEV	      WarnLog ( "Garbage Collection: Illegal values in table for defunct process");	      DbgLog  ( DL0, "Garbage collection: A process ( Index: %d, pid: %d ) showed %d sessions open on slot %s, but the global count for this slot is only %d",			ProcIndex, pProc->proc_id, *pProcSessions, SlotIndex, *pGlobalSessions );	    #endif /* DEV */	    *pGlobalSessions = 0;	  } else {	    *pGlobalSessions -= *pProcSessions;	  }	  *pProcSessions = 0;	} /* end if *pProcSessions */      } /* end for SlotIndex */      /*                                      */      /* NULL out everything except the mutex */      /*                                      */      #if PER_PROCESS_MUTEXES        /* Grab the mutex for this proc's shared memory data structure */#ifdef PKCS64        Err = msem_lock(&(pProc->proc_mutex),MSEM_IF_NOWAIT);#else         Err = pthread_mutex_trylock( &(pProc->proc_mutex) );#endif	if ( ( Err != 0 ) ) {	  /* We didn't get the lock! */	  /* Attempting to destroy a locked mutex results in undefined behavior */	  /* http://techlib.austin.ibm.com/techlib/manuals/adoclib/libs/basetrf1/pthreads.htm */	  DbgLog (DL0,"Unable to get per-process mutex for pid %d (%s) - skipping", pProc->proc_id, SysConst( Err ) );	  /* 	     The exit routine will figure out that this is an invalid process entry	     (by calling IsValidProcessEntry()), and won't prevent the slotd from exiting	     because of this entry.	     */	  continue;	}      #endif /* PER_PROCESS_MUTEXES */      memset( &(pProc->inuse),              '\0', sizeof(pProc->inuse) );      memset( &(pProc->proc_id),            '\0', sizeof(pProc->proc_id) );      memset( &(pProc->slotmap),            '\0', sizeof(pProc->slotmap) );      memset( &(pProc->blocking),           '\0', sizeof(pProc->blocking ));      memset( &(pProc->error),              '\0', sizeof(pProc->error) );      memset( &(pProc->slot_session_count), '\0', sizeof(pProc->slot_session_count) );      memset( &(pProc->reg_time),           '\0', sizeof(pProc->reg_time) );    } /* end if inuse && ValidPid */        #if PER_PROCESS_MUTEXES#ifdef PKCS64       msem_unlock(&(pProc->proc_mutex),0)    #else      pthread_mutex_unlock( &(pProc->proc_mutex));#endif    #endif /* PER_PROCESS_MUTEXES  */         } /* end for ProcIndex */  #ifdef PKCS64  msem_unlock(&(MemPtr->slt_mutex),0);#else  pthread_mutex_unlock ( &(MemPtr->slt_mutex) );#endif  DbgLog ( DL5, "Garbage collection: Released global shared memory lock");  return TRUE;  }/********************************************************************************* * IsValidProcessEntry - *  *     Checks to see if the process identifed by pid is the same process *     that registered with us *  *********************************************************************************/#ifdef PKCS64BOOL IsValidProcessEntry ( pid_t_64 pid, time_t_64 RegTime ) {#elseBOOL IsValidProcessEntry ( pid_t pid, time_t RegTime ) {#endif#ifdef PKCS64  pid_t                     Index     = (pid_t)pid;#else  pid_t                     Index     = pid;#endif  struct procsinfo64     ProcInfo[1]; /* getprocs wants arrays; I'm just being anal; I know it's stupid to declare an array of 1 element */  struct fdsinfo_2000    FileInfo[1]; /* if you pass a struct fdsinfo, you get a core dump */  int                    Count = 1;  int                    Err;    /* Note that Index is modified by this call; use pid to see what process id we're looking for afterwards */  if ( getprocs ( &(ProcInfo[0]), sizeof(ProcInfo), NULL, NULL, &Index, Count ) != Count ) {    Err = errno;    if ( Err == EINVAL ) {      /* The process was not found */      DbgLog(DL3, "IsValidProcessEntry: PID %d was not found in the process table (getprocs() returned %s)", pid, SysConst(Err) );      return FALSE;    } else {      /* some other error occurred */      DbgLog(DL3,"IsValidProcessEntry: getprocs() returned %s (%d; %#x)", SysConst(Err), Err, Err);      return FALSE;    }  } /* end if getprocs */  /* Okay, the process exists, now we see if it's really ours */  if ( ProcInfo[0].pi_pid == pid) {     if ( RegTime >= ProcInfo[0].pi_start ) {       return TRUE;     } else {       /* ProcInfo[0].pi_start contains the time at which the process began */       DbgLog(DL1, "IsValidProcessEntry: PID %d started at %lld; registered at %ld", pid, ProcInfo[0].pi_start, RegTime);       DbgLog(DL4, "IsValidProcessEntry: PID Returned %d flags at %#x; state at %#x index %d", ProcInfo[0].pi_pid, ProcInfo[0].pi_flags, ProcInfo[0].pi_state,Index);     }  }  return FALSE;}#endif // NO Garbage

⌨️ 快捷键说明

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