Пример #1
0
/*
 * Steps:
 *      1. Deactivate the service
 *      2. Free all memory used by the service and free the service itself
 *
 * Since this function may free all memory associated with the service as
 * well as the memory pointed by sp, only the value of sp should be used
 * after this call if the return value is 0 (i.e. no dereferencing of sp).
 *
 * Special services are never deactivated.
 */
int svc_release( struct service *sp )
{
   char *sid = SVC_ID( sp ) ;
   const char *func = "svc_release" ;

   if ( SVC_REFCOUNT(sp) == 0 )
   {
      msg( LOG_ERR, func, "%s: svc_release with 0 count", sid ) ;
      return( 0 ) ;
   }
   
   SVC_REFCOUNT(sp)-- ;
   if ( SVC_REFCOUNT(sp) == 0 )
   {
      if ( debug.on )
         msg( LOG_DEBUG, func, "ref count of service %s dropped to 0", sid ) ;
      if ( ! SC_IS_SPECIAL( SVC_CONF( sp ) ) )
      {
         if ( SVC_LOG(sp) )
            log_end( SC_LOG( SVC_CONF( sp ) ), SVC_LOG(sp) ) ;
         svc_deactivate( sp ) ;
         svc_free( sp ) ;
         sp = NULL;
      }
      else      /* this shouldn't happen */
         msg( LOG_WARNING, func,
            "ref count of special service %s dropped to 0", sid ) ;
      return( 0 ) ;
   }
   else
      return( SVC_REFCOUNT(sp) ) ;
}
Пример #2
0
/*
 * Check for reference counting errors.
 * Returns number of errors found.
 * Always set the number of running and retry servers.
 */
static unsigned refcount_check( struct service *sp, 
                                 unsigned *running_servers, 
                                 unsigned *retry_servers )
{
   char *sid = SVC_ID( sp ) ;
   unsigned errors = 0 ;
   int refs ;
   int refcount = SVC_REFCOUNT( sp ) ;
   const char *func = "refcount_check" ;

   if ( refcount <= 0 )
   {
      msg( LOG_ERR, func, "%s service has bad refcount: %d",
               sid, refcount ) ;
      errors++ ;
   }

   /*
    * The service table holds a reference to the service. The remaining
    * references must be from servers and connections.
    */
   refcount-- ;

   refs = count_refs( sp, SERVERS( ps ), running_servers ) ;
   if ( ! errors && refs > refcount )
   {
      msg( LOG_ERR, func,
         "running servers: too many references for %s (%d with max=%d)",
            sid, refs, refcount ) ;
      errors++ ;
   }

   refs = count_refs( sp, RETRIES( ps ), retry_servers ) ;
   if ( ! errors && refs > refcount )
   {
      msg( LOG_ERR, func,
         "retry servers: too many references for %s (%d with max=%d)",
            sid, refs, refcount ) ;
      errors++ ;
   }

   if ( errors && debug.on )
      msg( LOG_DEBUG, func, "%s: %d errors detected", sid, errors ) ;

   return( errors ) ;
}
Пример #3
0
struct service *svc_make_special( struct service_config *scp )
{
   struct service      *sp ;
   const char          *func = "svc_make_special" ;

   if ( ( sp = svc_new( scp ) ) == NULL )
   {
      out_of_memory( func ) ;
      return( NULL ) ;
   }

   SVC_NOT_GENERIC(sp) = 1 ;
   SVC_LOG(sp) = ps.rws.program_log ;
   SVC_REFCOUNT(sp) = 1 ;
   SVC_STATE(sp) = SVC_ACTIVE ;
   return( sp ) ;
}