packages feed

interprocess-0.2.1.0: cbits/common.c

#include "common.h"

#include <limits.h>
#include <stdatomic.h>
#include <string.h>
#include <time.h>

#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) || \
    defined(mingw32_HOST_OS)
#include <windows.h>
#define GetMyPid abs((int)GetCurrentProcessId())
#else
#include <unistd.h>
#define GetMyPid (int)getpid()
#endif

static atomic_int process_seed = 0;
static _Thread_local bool initialized = false;
static _Thread_local int process_id = 0;
static const char keytable[] =
    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
static const char prefix[] = "/HsIPC.";
#define keytableLength 62
#define prefixLength 7
// Leave a few symbol placeholders empty to be able to append some
// short suffixes to the object name in-place.
#define suffixLength 1

void genSharedObjectName(char* const name) {
  int seed = atomic_fetch_add_explicit(&process_seed, 1, memory_order_relaxed);
  // Init this once per thread
  if (!initialized) {
    initialized = true;
    srand(time(NULL));
    process_id = GetMyPid;
  }
  // Clear the name
  memset(name, 0, sizeof(SharedObjectName));
  memcpy(name, prefix, sizeof(prefix));
  // Combine three sources of uniqueness
  const int rands_num = 3;
  div_t rands[] = {{.quot = rand() ^ 0x19a628f6, .rem = 0},
                   {.quot = process_id ^ 0x003772a1, .rem = 0},
                   {.quot = seed ^ 0x028ab100, .rem = 0}};
  for (int i = prefixLength, j = 0, k = 0;
       i < SHARED_OBJECT_NAME_LENGTH - 1 - suffixLength && k < rands_num;
       i++, j = (j + 1) % rands_num) {
    rands[j] = div(rands[j].quot, keytableLength);
    name[i] = keytable[rands[j].rem];
    if (rands[j].quot == 0) k++;
  }
}

bool has_blocked_exceptions(StgStablePtr tso) {
  return (typeof(END_TSO_QUEUE))(
             ((StgTSO*)deRefStablePtr(tso))->blocked_exceptions) !=
         END_TSO_QUEUE;
}