📄 ipc_test.c
字号:
/*------------------------------------------------------------------------- * * ipc_test.c * Simplistic testbed for shared memory and semaphore code. * * This file allows for quick "smoke testing" of a PG semaphore or shared * memory implementation, with less overhead than compiling up a whole * installation. To use: * 1. Run configure, then edit src/include/pg_config.h to select the * USE_xxx_SEMAPHORES and USE_xxx_SHARED_MEMORY settings you want. * Also, adjust the pg_sema.c and pg_shmem.c symlinks in * src/backend/port/ if needed. * 2. In src/backend/port/, do "gmake ipc_test". * 3. Run ipc_test and see if it works. * 4. If it seems to work, try building the whole system and running * the parallel regression tests for a more complete test. * * * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION * $Header: /cvsroot/pgsql/src/backend/port/ipc_test.c,v 1.10 2003/08/26 15:38:24 tgl Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include <errno.h>#include <unistd.h>#include "miscadmin.h"#include "storage/ipc.h"#include "storage/pg_sema.h"#include "storage/pg_shmem.h"/********* stuff needed to satisfy references in shmem/sema code *********/volatile bool InterruptPending = false;volatile bool QueryCancelPending = false;volatile bool ProcDiePending = false;volatile bool ImmediateInterruptOK = false;volatile uint32 InterruptHoldoffCount = 0;volatile uint32 CritSectionCount = 0;const bool ExecBackend = false;bool IsUnderPostmaster = false;int MaxBackends = 32;int NBuffers = 64;#ifndef assert_enabledbool assert_enabled = true;#endif#define MAX_ON_EXITS 20static struct ONEXIT{ void (*function) (); Datum arg;} on_proc_exit_list[MAX_ON_EXITS], on_shmem_exit_list[MAX_ON_EXITS];static int on_proc_exit_index, on_shmem_exit_index;voidproc_exit(int code){ shmem_exit(code); while (--on_proc_exit_index >= 0) (*on_proc_exit_list[on_proc_exit_index].function) (code, on_proc_exit_list[on_proc_exit_index].arg); exit(code);}voidshmem_exit(int code){ while (--on_shmem_exit_index >= 0) (*on_shmem_exit_list[on_shmem_exit_index].function) (code, on_shmem_exit_list[on_shmem_exit_index].arg); on_shmem_exit_index = 0;}void on_shmem_exit(void (*function) (), Datum arg){ if (on_shmem_exit_index >= MAX_ON_EXITS) elog(FATAL, "out of on_shmem_exit slots"); on_shmem_exit_list[on_shmem_exit_index].function = function; on_shmem_exit_list[on_shmem_exit_index].arg = arg; ++on_shmem_exit_index;}voidon_exit_reset(void){ on_shmem_exit_index = 0; on_proc_exit_index = 0;}voidRecordSharedMemoryInLockFile(unsigned long id1, unsigned long id2){}voidProcessInterrupts(void){}intExceptionalCondition(char *conditionName, char *errorType, char *fileName, int lineNumber){ fprintf(stderr, "TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n", errorType, conditionName, fileName, lineNumber); abort(); return 0;}boolerrstart(int elevel, const char *filename, int lineno, const char *funcname){ return (elevel >= ERROR);}voiderrfinish(int dummy,...){ proc_exit(1);}voidelog_finish(int elevel, const char *fmt,...){ fprintf(stderr, "ERROR: %s\n", fmt); proc_exit(1);}interrcode(int sqlerrcode){ return 0; /* return value does not matter */}interrmsg(const char *fmt,...){ fprintf(stderr, "ERROR: %s\n", fmt); return 0; /* return value does not matter */}interrmsg_internal(const char *fmt,...){ fprintf(stderr, "ERROR: %s\n", fmt); return 0; /* return value does not matter */}interrdetail(const char *fmt,...){ fprintf(stderr, "DETAIL: %s\n", fmt); return 0; /* return value does not matter */}interrhint(const char *fmt,...){ fprintf(stderr, "HINT: %s\n", fmt); return 0; /* return value does not matter */}/********* here's the actual test *********/typedef struct MyStorage{ PGShmemHeader header; int flag; PGSemaphoreData sem;} MyStorage;intmain(int argc, char **argv){ MyStorage *storage; int cpid; printf("Creating shared memory ... "); fflush(stdout); storage = (MyStorage *) PGSharedMemoryCreate(8192, false, 5433); storage->flag = 1234; printf("OK\n"); printf("Creating semaphores ... "); fflush(stdout); PGReserveSemaphores(2, 5433); PGSemaphoreCreate(&storage->sem); printf("OK\n"); /* sema initial value is 1, so lock should work */ printf("Testing Lock ... "); fflush(stdout); PGSemaphoreLock(&storage->sem, false); printf("OK\n"); /* now sema value is 0, so trylock should fail */ printf("Testing TryLock ... "); fflush(stdout); if (PGSemaphoreTryLock(&storage->sem)) printf("unexpected result!\n"); else printf("OK\n"); /* unlocking twice and then locking twice should work... */ printf("Testing Multiple Lock ... "); fflush(stdout); PGSemaphoreUnlock(&storage->sem); PGSemaphoreUnlock(&storage->sem); PGSemaphoreLock(&storage->sem, false); PGSemaphoreLock(&storage->sem, false); printf("OK\n"); /* check Reset too */ printf("Testing Reset ... "); fflush(stdout); PGSemaphoreUnlock(&storage->sem); PGSemaphoreReset(&storage->sem); if (PGSemaphoreTryLock(&storage->sem)) printf("unexpected result!\n"); else printf("OK\n"); /* Fork a child process and see if it can communicate */ printf("Forking child process ... "); fflush(stdout); cpid = fork(); if (cpid == 0) { /* In child */ on_exit_reset(); sleep(3); storage->flag++; PGSemaphoreUnlock(&storage->sem); proc_exit(0); } if (cpid < 0) { /* Fork failed */ printf("failed: %s\n", strerror(errno)); proc_exit(1); } printf("forked child pid %d OK\n", cpid); if (storage->flag != 1234) printf("Wrong value found in shared memory!\n"); printf("Waiting for child (should wait 3 sec here) ... "); fflush(stdout); PGSemaphoreLock(&storage->sem, false); printf("OK\n"); if (storage->flag != 1235) printf("Wrong value found in shared memory!\n"); /* Test shutdown */ printf("Running shmem_exit processing ... "); fflush(stdout); shmem_exit(0); printf("OK\n"); printf("Tests complete.\n"); proc_exit(0); return 0; /* not reached */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -