tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

semaping.c (5378B)


      1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #include "nspr.h"
      7 #include "plgetopt.h"
      8 
      9 #include <stdio.h>
     10 
     11 #ifdef DEBUG
     12 #  define SEM_D "D"
     13 #else
     14 #  define SEM_D
     15 #endif
     16 #ifdef IS_64
     17 #  define SEM_64 "64"
     18 #else
     19 #  define SEM_64
     20 #endif
     21 
     22 #define SHM_NAME "/tmp/counter" SEM_D SEM_64
     23 #define SEM_NAME1 "/tmp/foo.sem" SEM_D SEM_64
     24 #define SEM_NAME2 "/tmp/bar.sem" SEM_D SEM_64
     25 #define EXE_NAME "semapong"
     26 #define SEM_MODE 0666
     27 #define SHM_MODE 0666
     28 #define ITERATIONS 1000
     29 
     30 static PRBool debug_mode = PR_FALSE;
     31 static PRIntn iterations = ITERATIONS;
     32 static PRSem *sem1, *sem2;
     33 
     34 static void Help(void) {
     35  fprintf(stderr, "semaping test program usage:\n");
     36  fprintf(stderr, "\t-d           debug mode         (FALSE)\n");
     37  fprintf(stderr, "\t-c <count>   loop count         (%d)\n", ITERATIONS);
     38  fprintf(stderr, "\t-h           this message\n");
     39 } /* Help */
     40 
     41 int main(int argc, char** argv) {
     42  PRProcess* proc;
     43  PRIntn i;
     44  char* child_argv[32];
     45  char** child_arg;
     46  char iterations_buf[32];
     47  PRSharedMemory* shm;
     48  PRIntn* counter_addr;
     49  PRInt32 exit_code;
     50  PLOptStatus os;
     51  PLOptState* opt = PL_CreateOptState(argc, argv, "dc:h");
     52 
     53  while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
     54    if (PL_OPT_BAD == os) {
     55      continue;
     56    }
     57    switch (opt->option) {
     58      case 'd': /* debug mode */
     59        debug_mode = PR_TRUE;
     60        break;
     61      case 'c': /* loop count */
     62        iterations = atoi(opt->value);
     63        break;
     64      case 'h':
     65      default:
     66        Help();
     67        return 2;
     68    }
     69  }
     70  PL_DestroyOptState(opt);
     71 
     72  if (PR_DeleteSharedMemory(SHM_NAME) == PR_SUCCESS) {
     73    fprintf(stderr,
     74            "warning: removed shared memory %s left over "
     75            "from previous run\n",
     76            SHM_NAME);
     77  }
     78  if (PR_DeleteSemaphore(SEM_NAME1) == PR_SUCCESS) {
     79    fprintf(stderr,
     80            "warning: removed semaphore %s left over "
     81            "from previous run\n",
     82            SEM_NAME1);
     83  }
     84  if (PR_DeleteSemaphore(SEM_NAME2) == PR_SUCCESS) {
     85    fprintf(stderr,
     86            "warning: removed semaphore %s left over "
     87            "from previous run\n",
     88            SEM_NAME2);
     89  }
     90 
     91  shm = PR_OpenSharedMemory(SHM_NAME, sizeof(*counter_addr), PR_SHM_CREATE,
     92                            SHM_MODE);
     93  if (NULL == shm) {
     94    fprintf(stderr, "PR_OpenSharedMemory failed (%d, %d)\n", PR_GetError(),
     95            PR_GetOSError());
     96    exit(1);
     97  }
     98  counter_addr = PR_AttachSharedMemory(shm, 0);
     99  if (NULL == counter_addr) {
    100    fprintf(stderr, "PR_AttachSharedMemory failed\n");
    101    exit(1);
    102  }
    103  *counter_addr = 0;
    104  sem1 = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 1);
    105  if (NULL == sem1) {
    106    fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n", PR_GetError(),
    107            PR_GetOSError());
    108    exit(1);
    109  }
    110  sem2 = PR_OpenSemaphore(SEM_NAME2, PR_SEM_CREATE, SEM_MODE, 0);
    111  if (NULL == sem2) {
    112    fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n", PR_GetError(),
    113            PR_GetOSError());
    114    exit(1);
    115  }
    116 
    117  child_arg = &child_argv[0];
    118  *child_arg++ = EXE_NAME;
    119  if (debug_mode != PR_FALSE) {
    120    *child_arg++ = "-d";
    121  }
    122  if (iterations != ITERATIONS) {
    123    *child_arg++ = "-c";
    124    PR_snprintf(iterations_buf, sizeof(iterations_buf), "%d", iterations);
    125    *child_arg++ = iterations_buf;
    126  }
    127  *child_arg = NULL;
    128  proc = PR_CreateProcess(child_argv[0], child_argv, NULL, NULL);
    129  if (NULL == proc) {
    130    fprintf(stderr, "PR_CreateProcess failed\n");
    131    exit(1);
    132  }
    133 
    134  /*
    135   * Process 1 waits on semaphore 1 and posts to semaphore 2.
    136   */
    137  for (i = 0; i < iterations; i++) {
    138    if (PR_WaitSemaphore(sem1) == PR_FAILURE) {
    139      fprintf(stderr, "PR_WaitSemaphore failed\n");
    140      exit(1);
    141    }
    142    if (*counter_addr == 2 * i) {
    143      if (debug_mode) {
    144        printf("process 1: counter = %d\n", *counter_addr);
    145      }
    146    } else {
    147      fprintf(stderr, "process 1: counter should be %d but is %d\n", 2 * i,
    148              *counter_addr);
    149      exit(1);
    150    }
    151    (*counter_addr)++;
    152    if (PR_PostSemaphore(sem2) == PR_FAILURE) {
    153      fprintf(stderr, "PR_PostSemaphore failed\n");
    154      exit(1);
    155    }
    156  }
    157  if (PR_DetachSharedMemory(shm, counter_addr) == PR_FAILURE) {
    158    fprintf(stderr, "PR_DetachSharedMemory failed\n");
    159    exit(1);
    160  }
    161  if (PR_CloseSharedMemory(shm) == PR_FAILURE) {
    162    fprintf(stderr, "PR_CloseSharedMemory failed\n");
    163    exit(1);
    164  }
    165  if (PR_CloseSemaphore(sem1) == PR_FAILURE) {
    166    fprintf(stderr, "PR_CloseSemaphore failed\n");
    167  }
    168  if (PR_CloseSemaphore(sem2) == PR_FAILURE) {
    169    fprintf(stderr, "PR_CloseSemaphore failed\n");
    170  }
    171 
    172  if (PR_WaitProcess(proc, &exit_code) == PR_FAILURE) {
    173    fprintf(stderr, "PR_WaitProcess failed\n");
    174    exit(1);
    175  }
    176  if (exit_code != 0) {
    177    fprintf(stderr, "process 2 failed with exit code %d\n", exit_code);
    178    exit(1);
    179  }
    180 
    181  if (PR_DeleteSharedMemory(SHM_NAME) == PR_FAILURE) {
    182    fprintf(stderr, "PR_DeleteSharedMemory failed\n");
    183  }
    184  if (PR_DeleteSemaphore(SEM_NAME1) == PR_FAILURE) {
    185    fprintf(stderr, "PR_DeleteSemaphore failed\n");
    186  }
    187  if (PR_DeleteSemaphore(SEM_NAME2) == PR_FAILURE) {
    188    fprintf(stderr, "PR_DeleteSemaphore failed\n");
    189  }
    190  printf("PASS\n");
    191  return 0;
    192 }