Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "postgres.h"
00015
00016 #include "miscadmin.h"
00017 #include "storage/ipc.h"
00018 #include "storage/pg_sema.h"
00019
00020 static HANDLE *mySemSet;
00021 static int numSems;
00022 static int maxSems;
00023
00024 static void ReleaseSemaphores(int code, Datum arg);
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 void
00036 PGReserveSemaphores(int maxSemas, int port)
00037 {
00038 mySemSet = (HANDLE *) malloc(maxSemas * sizeof(HANDLE));
00039 if (mySemSet == NULL)
00040 elog(PANIC, "out of memory");
00041 numSems = 0;
00042 maxSems = maxSemas;
00043
00044 on_shmem_exit(ReleaseSemaphores, 0);
00045 }
00046
00047
00048
00049
00050
00051
00052 static void
00053 ReleaseSemaphores(int code, Datum arg)
00054 {
00055 int i;
00056
00057 for (i = 0; i < numSems; i++)
00058 CloseHandle(mySemSet[i]);
00059 free(mySemSet);
00060 }
00061
00062
00063
00064
00065
00066
00067 void
00068 PGSemaphoreCreate(PGSemaphore sema)
00069 {
00070 HANDLE cur_handle;
00071 SECURITY_ATTRIBUTES sec_attrs;
00072
00073
00074 Assert(!IsUnderPostmaster);
00075
00076 if (numSems >= maxSems)
00077 elog(PANIC, "too many semaphores created");
00078
00079 ZeroMemory(&sec_attrs, sizeof(sec_attrs));
00080 sec_attrs.nLength = sizeof(sec_attrs);
00081 sec_attrs.lpSecurityDescriptor = NULL;
00082 sec_attrs.bInheritHandle = TRUE;
00083
00084
00085 cur_handle = CreateSemaphore(&sec_attrs, 1, 32767, NULL);
00086 if (cur_handle)
00087 {
00088
00089 *sema = cur_handle;
00090 mySemSet[numSems++] = cur_handle;
00091 }
00092 else
00093 ereport(PANIC,
00094 (errmsg("could not create semaphore: error code %lu", GetLastError())));
00095 }
00096
00097
00098
00099
00100
00101
00102 void
00103 PGSemaphoreReset(PGSemaphore sema)
00104 {
00105
00106
00107
00108
00109 while (PGSemaphoreTryLock(sema));
00110 }
00111
00112
00113
00114
00115
00116
00117
00118 void
00119 PGSemaphoreLock(PGSemaphore sema, bool interruptOK)
00120 {
00121 DWORD ret;
00122 HANDLE wh[2];
00123
00124
00125
00126
00127
00128
00129 wh[0] = pgwin32_signal_event;
00130 wh[1] = *sema;
00131
00132
00133
00134
00135
00136
00137
00138 do
00139 {
00140 ImmediateInterruptOK = interruptOK;
00141 CHECK_FOR_INTERRUPTS();
00142
00143 ret = WaitForMultipleObjectsEx(2, wh, FALSE, INFINITE, TRUE);
00144
00145 if (ret == WAIT_OBJECT_0)
00146 {
00147
00148 pgwin32_dispatch_queued_signals();
00149 errno = EINTR;
00150 }
00151 else if (ret == WAIT_OBJECT_0 + 1)
00152 {
00153
00154 errno = 0;
00155 }
00156 else
00157
00158 errno = EIDRM;
00159
00160 ImmediateInterruptOK = false;
00161 } while (errno == EINTR);
00162
00163 if (errno != 0)
00164 ereport(FATAL,
00165 (errmsg("could not lock semaphore: error code %lu", GetLastError())));
00166 }
00167
00168
00169
00170
00171
00172
00173 void
00174 PGSemaphoreUnlock(PGSemaphore sema)
00175 {
00176 if (!ReleaseSemaphore(*sema, 1, NULL))
00177 ereport(FATAL,
00178 (errmsg("could not unlock semaphore: error code %lu", GetLastError())));
00179 }
00180
00181
00182
00183
00184
00185
00186 bool
00187 PGSemaphoreTryLock(PGSemaphore sema)
00188 {
00189 DWORD ret;
00190
00191 ret = WaitForSingleObject(*sema, 0);
00192
00193 if (ret == WAIT_OBJECT_0)
00194 {
00195
00196 return true;
00197 }
00198 else if (ret == WAIT_TIMEOUT)
00199 {
00200
00201 errno = EAGAIN;
00202 return false;
00203 }
00204
00205
00206 ereport(FATAL,
00207 (errmsg("could not try-lock semaphore: error code %lu", GetLastError())));
00208
00209
00210 return false;
00211 }