Пример #1
0
void *sha_checkout(ShmemArray *array, unsigned int elementNumber)
{
   void *element;
   if (elementNumber < array->elementCount)
   {
      /* read locks block if a write is pending */
#ifdef EXTRA_DEBUGGING_LOGS
       WOLog(WO_DBG, "sha_checkout(): about to check out %s element %d", array->name, elementNumber);
#endif
      WA_lock(array->elements[elementNumber].writeLock);
      WA_lock(array->elements[elementNumber].lock);
      WA_unlock(array->elements[elementNumber].writeLock);
      element = array->elements[elementNumber].element;
      /* if this was the first read lock by this process, obtain a file lock on the data as well */
      if (array->elements[elementNumber].lockCount == 0)
         array->elements[elementNumber].lockHandle = WOShmem_lock(element, array->elementSize, 0);
      array->elements[elementNumber].lockCount++;
      WA_unlock(array->elements[elementNumber].lock);
#ifdef EXTRA_DEBUGGING_LOGS
       WOLog(WO_DBG, "sha_checkout(): checked out %s element %d", array->name, elementNumber);
#endif
   } else {
      element = NULL;
      WOLog(WO_ERR, "sha_checkout(): failed to check out %s element %d", array->name, elementNumber);
   }

   return element;
}
Пример #2
0
void *sha_lock(ShmemArray *array, unsigned int elementNumber)
{
   void *element;
   if (elementNumber < array->elementCount)
   {
#ifdef EXTRA_DEBUGGING_LOGS
      WOLog(WO_DBG, "sha_lock(): about to lock %s element %d", array->name, elementNumber);
#endif
      /* block read lock requests */
      WA_lock(array->elements[elementNumber].writeLock);
      WA_lock(array->elements[elementNumber].lock);
      int maxTry = 10000;
      while (array->elements[elementNumber].lockCount > 0 && maxTry-- > 0)
      {
         WA_unlock(array->elements[elementNumber].lock);
         WA_yield();
         WA_lock(array->elements[elementNumber].lock);
      }

      if(array->elements[elementNumber].lockCount <= 0)
      {
         element = array->elements[elementNumber].element;
         array->elements[elementNumber].lockHandle = WOShmem_lock(element, array->elementSize, 1);
         WA_unlock(array->elements[elementNumber].lock);
#ifdef EXTRA_DEBUGGING_LOGS
         WOLog(WO_DBG, "sha_lock(): locked %s element %d", array->name, elementNumber);
#endif
      } else
      {
         WA_unlock(array->elements[elementNumber].lock);
         WA_unlock(array->elements[elementNumber].writeLock);
         element = NULL;
         WOLog(WO_ERR, "sha_lock(): element already locked: %s / %d", array->name, elementNumber);
      }
   } else {
      element = NULL;
      WOLog(WO_ERR, "sha_lock(): failed to lock %s element %d", array->name, elementNumber);
   }
   return element;
}
Пример #3
0
/*
 * Obtain a lock on a chunk of shared memory. The range of memory
 * begins add address addr, and is size bytes in length. If exclusive
 * is zero the lock is a shared lock for read only access to the region.
 * If exclusive is nonzero the lock is an exclusive lock for write
 * access to the region.
 * The return value is a handle which must be supplied to the WOShmem_unlock
 * function when the lock is released. If some error occurrs and
 * a lock could not be obtained, NULL is returned.
 */
void *WOShmem_lock(const void *addr, size_t size, int exclusive)
{
   struct flock *lockInfo;
   ptrdiff_t offset;
   LockInfo *info = NULL;

   if (addr && WOShmem_fd != -1)
   {
      offset = addr_to_offset(addr);
      if (offset >= 0 && offset + size < WOShmem_size)
      {
         /* This gets called a lot, so as an optimization to avoid the malloc() overhead */
         /* we keep a cache of LockInfo's. */
         WA_lock(WOShmem_mutex);
         info = WOShmem_lockInfoCache;
         if (info)
            WOShmem_lockInfoCache = info->cache;
         WA_unlock(WOShmem_mutex);

         /* if there wasn't one in the cache, malloc a new one */
         if (!info)
            info = WOMALLOC(sizeof(LockInfo));
         
         if (info)
         {
            lockInfo = &info->flockInfo;
            if (lock_file_section(WOShmem_fd, offset, size, lockInfo, exclusive))
            {
               /* failed; put the info struct back on the cache */
               WA_lock(WOShmem_mutex);
               info->cache = WOShmem_lockInfoCache;
               WOShmem_lockInfoCache = info;
               WA_unlock(WOShmem_mutex);
               info = NULL;
            }
         }
      }
   }
   return info;
}
Пример #4
0
static String *tr_uniqueID()
{
   String *uniqueID;
   char counter_str[9];
   int count;

   uniqueID = str_create(uniqueID_str, 25);

   WA_lock(tr_lock);
   count = uniqueID_counter++;
   WA_unlock(tr_lock);
   sprintf(counter_str, "%8.8x", count);
   str_appendLength(uniqueID, counter_str, 8);
   return uniqueID;
}
Пример #5
0
void sha_unlock(ShmemArray *array, unsigned int elementNumber)
{
   if (elementNumber < array->elementCount)
   {
#ifdef EXTRA_DEBUGGING_LOGS
      WOLog(WO_DBG, "sha_unlock(): about to unlock %s element %d", array->name, elementNumber);
#endif
      WA_lock(array->elements[elementNumber].lock);
      /* release the file lock on the data */
      WOShmem_unlock(array->elements[elementNumber].lockHandle);
      array->elements[elementNumber].lockHandle = NULL;
      WA_unlock(array->elements[elementNumber].lock);
      WA_unlock(array->elements[elementNumber].writeLock);
#ifdef EXTRA_DEBUGGING_LOGS
      WOLog(WO_DBG, "sha_unlock(): unlocked %s element %d", array->name, elementNumber);
#endif
   }
}
Пример #6
0
/*
 *	Only consult the flag (existence of /tmp/logWebObjects) once every
 *	so many log attempts.  This reduces the number of stats() to
 *	(hopefully) once per request on average.
 */
inline
static int shouldLog()
{
#ifdef	ALWAYS_LOG
   return 1;
#else
   static int _shouldLog = 0;
   static time_t statTime = 0;
   time_t now;

   now = time(NULL);
   WA_lock(logMutex);
   if (statTime < now) {
      struct stat statbuf;
      statTime = now + STATINTERVAL;		/* reset timer */
      _shouldLog = ( (stat(logFlag,&statbuf) == 0) && (statbuf.st_uid == 0) );
   }
   WA_unlock(logMutex);
   return _shouldLog;
#endif
}
Пример #7
0
void sha_checkin(ShmemArray *array, unsigned int elementNumber)
{
   if (elementNumber < array->elementCount)
   {
#ifdef EXTRA_DEBUGGING_LOGS
      WOLog(WO_DBG, "sha_checkin(): about to check in %s element %d", array->name, elementNumber);
#endif
      WA_lock(array->elements[elementNumber].lock);
      array->elements[elementNumber].lockCount--;
      /* if this was the last read lock by this process, release the file lock on the data as well */
      if (array->elements[elementNumber].lockCount == 0)
      {
         WOShmem_unlock(array->elements[elementNumber].lockHandle);
         array->elements[elementNumber].lockHandle = NULL;
      }
      WA_unlock(array->elements[elementNumber].lock);
#ifdef EXTRA_DEBUGGING_LOGS
      WOLog(WO_DBG, "sha_checkin(): checked in %s element %d", array->name, elementNumber);
#endif
   }
}
Пример #8
0
/*
 * Release a lock obtained by WOShmem_lock. handle is the value returned
 * by WOShmem_lock.
 */
void WOShmem_unlock(void *handle)
{
   if (handle)
   {
      LockInfo *info = (LockInfo *)handle;
      struct flock *lockInfo = &info->flockInfo;
      lockInfo->l_type = F_UNLCK;
      if (fcntl(WOShmem_fd, F_SETLK, lockInfo) == -1)
      {
         char *errMsg = WA_errorDescription(WA_error());
         WOLog(WO_ERR,"WOShmem_unlock(): failed to unlock %d bytes at 0x%x: %s", lockInfo->l_len, lockInfo->l_start, errMsg);
         WA_freeErrorDescription(errMsg);
         /* how should we recover? */
      }
      /* put the info struct back on the cache */
      WA_lock(WOShmem_mutex);
      info->cache = WOShmem_lockInfoCache;
      WOShmem_lockInfoCache = info;
      WA_unlock(WOShmem_mutex);
   }
}
Пример #9
0
void WOLog(int level, const char *format, ...)
{
   FILE *log;
   va_list ap;
   int do_it;
#if defined(TIMESTAMP_LOG_MESSAGES)
   struct tm *t;
   time_t now;
   char timestamp[64];
#endif

   if (level < baselevel)
      return;

   if (! initialized )
	   return;

   do_it = shouldLog();
   if ( do_it ) {
      /*
       * plenty of people have complained that we need to timestamp
       * the log entries.  the problem is that mktime & friends aren't
       * reentrant.
       */
#if defined(TIMESTAMP_LOG_MESSAGES)
      WA_lock(logMutex);
      time(&now);
      t = localtime(&now);
      strftime(timestamp, sizeof(timestamp), "%d-%b-%Y %T - ", t);
      WA_unlock(logMutex);
#endif
      log = fopen(logPath, "a+");
      if (log != NULL) {
#if defined(TIMESTAMP_LOG_MESSAGES)
         fprintf(log, timestamp);
#endif
         fprintf(log,"%s: ", WOLogLevel[level]);
         va_start(ap, format);
         vfprintf(log, format, ap);
         va_end(ap);
         fprintf(log,"\n");
         fclose(log);
      }
   }


   /*
    *	if the error is serious, include it into the server's log
    */
#if	defined(Netscape) || defined(Apache) || defined(IIS)
   if (level == WO_ERR) {
      String *str;
      str = str_create(NULL, 128);
      va_start(ap,format);
      str_vappendf(str, format, ap);
      va_end(ap);
#if defined(Netscape)
      log_error(0,"WebObjects",NULL,NULL,str->text);
#elif defined(Apache)
      ap_log_error("WebObjects",0, APLOG_ERR, _webobjects_server, str->text);
#elif defined(IIS)
      /*
       *	again, we're stymied because we don't have a ptr to the
       *	server struct
       * /
       {
          LPDWORD len = strlen(logstr);
          ServerSupportFunction(p->ConnID, HSE_APPEND_LOG_PARAMETER,
                                str->text, &len, (LPDWORD)NULL);
       }
       */
#endif
      str_free(str);
   }
#endif
}