Esempio n. 1
0
ConstUnicode
Unicode_GetStatic(const char *asciiBytes, // IN
                  Bool unescape)          // IN
{
   Unicode result = NULL;
   HashTable *stringTable;

   if (unescape) {
      stringTable = HashTable_AllocOnce(&UnicodeUnescapedStringTable, 4096, 
                                        HASH_FLAG_ATOMIC | HASH_STRING_KEY,
                                        UnicodeHashFree);
   } else {
      stringTable = HashTable_AllocOnce(&UnicodeStringTable, 4096, 
                                        HASH_FLAG_ATOMIC | HASH_STRING_KEY,
                                        UnicodeHashFree);
   }

   /*
    * Attempt a lookup for the key value; if it is found things are easy and
    * fine. Otherwise HashTable_LookupOrInsert is used to attempt to enter
    * the data in a racey manner. Should multiple threads attempt to enter
    * the same key concurrently one thread will get the entered data and the
    * other threads will detect that their entries were rejected; they
    * discard their copies of the data and use the entered data (values
    * will be stable).
    */

   if (!HashTable_Lookup(stringTable, asciiBytes, (void **) &result)) {
      Unicode newData = UnicodeAllocStatic(asciiBytes, unescape);

      if (newData) {
         result = HashTable_LookupOrInsert(stringTable, asciiBytes, newData);

         if (result != newData) {
            Unicode_Free(newData);
         }
      }
   }

   return result;
}
Esempio n. 2
0
static HolderContext *
MXUserGetHolderContext(MXUserRWLock *lock)  // IN:
{
   HolderContext *result;
   void *threadID = MXUserCastedThreadID();

   ASSERT(lock->holderTable);

   if (!HashTable_Lookup(lock->holderTable, threadID, (void **) &result)) {
      HolderContext *newContext = Util_SafeMalloc(sizeof(HolderContext));

      newContext->holdStart = 0;
      newContext->state = RW_UNLOCKED;

      result = HashTable_LookupOrInsert(lock->holderTable, threadID,
                                        (void *) newContext);

      if (result != newContext) {
         free(newContext);
      }
   }

   return result;
}
Esempio n. 3
0
const char *
Err_Errno2String(Err_Number errorNumber) // IN
{
   HashTable *numTable;
   HashTable *ptrTable;
   ErrInfo *info;
   ErrInfo *oldInfo;
   Err_Number oldErrno = Err_Errno();

   ASSERT(errorNumber != ERR_INVALID);

   /*
    * Look up the error in numTable.
    * Or insert it if it's not there.
    */

   numTable = NUMTABLE();
   if (!HashTable_Lookup(numTable, (void *) (uintptr_t) errorNumber,
			 (void **) &info)) {
      char buf[2048];
      const char *p;
      size_t n;

      /*
       * Convert number to string and build the info structure.
       */

      p = ErrErrno2String(errorNumber, buf, sizeof buf);

      info = Util_SafeMalloc(sizeof *info);
      info->number = errorNumber;
      info->string = Util_SafeStrdup(p);

      /*
       * To be safe, make sure the end of the string is at
       * a UTF-8 boundary, but we can only do this when the
       * string is in our buffer (it may not be).
       */

      n = strlen(info->string);
      n = CodeSet_Utf8FindCodePointBoundary(info->string, n);
      info->string[n] = '\0';

      /*
       * Try to insert new info into numTable.
       * If that fails, then we must have lost out to someone else.
       * Use theirs in that case.
       */

      oldInfo = HashTable_LookupOrInsert(numTable,
				         (void *) (uintptr_t) errorNumber,
				         info);
      if (oldInfo != info) {
	 ASSERT(oldInfo->number == info->number);
	 ASSERT(Str_Strcmp(oldInfo->string, info->string) == 0);
	 free(info->string);
	 free(info);
	 info = oldInfo;
      }
   }

   /*
    * Try to insert info into ptrTable.
    * We need to do it even if we didn't create this entry,
    * because we may get here before the other guy (who created
    * the entry and inserted it into numTable).
    */

   ptrTable = PTRTABLE();
   oldInfo = HashTable_LookupOrInsert(ptrTable, info->string, info);
   ASSERT(oldInfo == info);

#if defined VMX86_DEBUG && defined __linux__
   {
      HashTable *strTable = STRTABLE();
      ErrInfo *i = HashTable_LookupOrInsert(strTable, info->string, info);
      ASSERT(i == info);
   }
#endif

   Err_SetErrno(oldErrno);
   return info->string;
}
Esempio n. 4
0
static HashTable *
SNEBuildHash(const char **compatEnviron)
                // IN: original "compatibility" environment
{
   HashTable *environTable;
   const char **p;

   /*
    * Number of buckets picked arbitrarily.  We're more interested in having an
    * associative array than raw table performance.
    */
   environTable = HashTable_Alloc(64, HASH_STRING_KEY | HASH_FLAG_COPYKEY, free);

   for (p = compatEnviron; p && *p; p++) {
      const size_t prefixLength = sizeof "VMWARE_" - 1;
      char *key;
      char *value;
      unsigned int index;

      index = 0;
      key = StrUtil_GetNextToken(&index, *p, "=");
      if (!key) {
         /* XXX Must empty environment variables still contain a '=' delimiter? */
         Debug("%s: Encountered environment entry without '='.\n", __func__);
         continue;
      }

      /*
       * Copy the value beginning after the '=' delimiter (even if it's empty).
       */
      ++index;
      value = Util_SafeStrdup(&(*p)[index]);

      if (StrUtil_StartsWith(key, "VMWARE_") &&
          key[prefixLength] != '\0' &&
          (value[0] == '0' || value[0] == '1')) {
         /*
          * Okay, this appears to be one of the wrapper's variables, so let's
          * figure out the original environment variable name (by just indexing
          * past the prefix) and value (by indexing past the "was this variable
          * in the native environment?" marker).
          *
          * XXX Should we move this marker to a separate header?
          */
         char *realKey = &key[prefixLength];
         char *realValue = (value[0] == '0')
                           ? NULL
                           : Util_SafeStrdup(&value[1]);
         HashTable_ReplaceOrInsert(environTable, realKey, realValue);
      } else {
         HashTable_LookupOrInsert(environTable, key, value);
      }

      /*
       * The hash table makes a copy of our key, and it takes ownership of inserted
       * values (via our passed freeing function).  So that means we're responsible
       * for freeing 'key', but -not- 'value'.
       */
      free(key);
   }

   return environTable;
}