12
12
#include "utils/portal.h"
13
13
#include "tcop/pquery.h"
14
14
#include "utils/guc.h"
15
+ #include "tcop/tcopprot.h"
15
16
16
17
#include "bgwpool.h"
17
18
#include "mm.h"
@@ -25,11 +26,17 @@ static BgwPool* MtmPool;
25
26
void BgwPoolStaticWorkerMainLoop (Datum arg );
26
27
void BgwPoolDynamicWorkerMainLoop (Datum arg );
27
28
28
- static void BgwShutdownWorker (int sig )
29
+ static void
30
+ BgwShutdownHandler (int sig )
29
31
{
30
- if (MtmPool ) {
31
- BgwPoolStop (MtmPool );
32
- }
32
+ Assert (MtmPool != NULL );
33
+ BgwPoolStop (MtmPool );
34
+
35
+ /*
36
+ * set ProcDiePending for cases when we are waiting on latch somewhere
37
+ * deep inside our execute() function.
38
+ */
39
+ die (sig );
33
40
}
34
41
35
42
static void BgwPoolMainLoop (BgwPool * pool )
@@ -44,10 +51,9 @@ static void BgwPoolMainLoop(BgwPool* pool)
44
51
MtmIsLogicalReceiver = true;
45
52
MtmPool = pool ;
46
53
47
- // XXX: fix that
48
- pqsignal (SIGINT , BgwShutdownWorker );
49
- pqsignal (SIGQUIT , BgwShutdownWorker );
50
- pqsignal (SIGTERM , BgwShutdownWorker );
54
+ pqsignal (SIGINT , StatementCancelHandler );
55
+ pqsignal (SIGQUIT , BgwShutdownHandler );
56
+ pqsignal (SIGTERM , BgwShutdownHandler );
51
57
pqsignal (SIGHUP , PostgresSigHupHandler );
52
58
53
59
BackgroundWorkerUnblockSignals ();
@@ -93,8 +99,13 @@ static void BgwPoolMainLoop(BgwPool* pool)
93
99
pool -> lastPeakTime = 0 ;
94
100
}
95
101
SpinLockRelease (& pool -> lock );
102
+
103
+ /* Ignore cancel that arrived before we started current command */
104
+ QueryCancelPending = false;
105
+
96
106
pool -> executor (work , size , NULL );
97
- pfree (work );
107
+ pfree (work );
108
+
98
109
SpinLockAcquire (& pool -> lock );
99
110
pool -> active -= 1 ;
100
111
pool -> lastPeakTime = 0 ;
@@ -107,6 +118,8 @@ static void BgwPoolMainLoop(BgwPool* pool)
107
118
void BgwPoolInit (BgwPool * pool , BgwPoolExecutor executor , char const * dbname , char const * dbuser , size_t queueSize , size_t nWorkers )
108
119
{
109
120
MtmPool = pool ;
121
+
122
+ pool -> bgwhandles = (BackgroundWorkerHandle * * ) ShmemAlloc (MtmMaxWorkers * sizeof (BackgroundWorkerHandle * ));
110
123
pool -> queue = (char * )ShmemAlloc (queueSize );
111
124
if (pool -> queue == NULL ) {
112
125
elog (PANIC , "Failed to allocate memory for background workers pool: %lld bytes requested" , (long64 )queueSize );
@@ -148,7 +161,6 @@ void BgwPoolDynamicWorkerMainLoop(Datum arg)
148
161
149
162
void BgwPoolStart (BgwPool * pool , char * poolName )
150
163
{
151
- int i ;
152
164
BackgroundWorker worker ;
153
165
154
166
MemSet (& worker , 0 , sizeof (BackgroundWorker ));
@@ -159,13 +171,6 @@ void BgwPoolStart(BgwPool* pool, char *poolName)
159
171
worker .bgw_restart_time = MULTIMASTER_BGW_RESTART_TIMEOUT ;
160
172
161
173
strncpy (pool -> poolName , poolName , MAX_NAME_LEN );
162
-
163
- for (i = 0 ; i < pool -> nWorkers ; i ++ )
164
- {
165
- snprintf (worker .bgw_name , BGW_MAXLEN , "%s_worker_%d" , pool -> poolName , i + 1 );
166
- worker .bgw_main_arg = PointerGetDatum (pool );
167
- RegisterBackgroundWorker (& worker );
168
- }
169
174
}
170
175
171
176
size_t BgwPoolGetQueueSize (BgwPool * pool )
@@ -180,25 +185,29 @@ size_t BgwPoolGetQueueSize(BgwPool* pool)
180
185
181
186
static void BgwStartExtraWorker (BgwPool * pool )
182
187
{
183
- if (pool -> nWorkers < MtmMaxWorkers ) {
184
- timestamp_t now = MtmGetSystemTime ();
185
- /*if (pool->lastDynamicWorkerStartTime + MULTIMASTER_BGW_RESTART_TIMEOUT*USECS_PER_SEC < now)*/
186
- {
187
- BackgroundWorker worker ;
188
- BackgroundWorkerHandle * handle ;
189
- MemSet (& worker , 0 , sizeof (BackgroundWorker ));
190
- worker .bgw_flags = BGWORKER_SHMEM_ACCESS | BGWORKER_BACKEND_DATABASE_CONNECTION ;
191
- worker .bgw_start_time = BgWorkerStart_ConsistentState ;
192
- sprintf (worker .bgw_library_name , "multimaster" );
193
- sprintf (worker .bgw_function_name , "BgwPoolDynamicWorkerMainLoop" );
194
- worker .bgw_restart_time = MULTIMASTER_BGW_RESTART_TIMEOUT ;
195
- snprintf (worker .bgw_name , BGW_MAXLEN , "%s-dynworker-%d" , pool -> poolName , (int )++ pool -> nWorkers );
196
- worker .bgw_main_arg = PointerGetDatum (pool );
197
- pool -> lastDynamicWorkerStartTime = now ;
198
- if (!RegisterDynamicBackgroundWorker (& worker , & handle )) {
199
- elog (WARNING , "Failed to start dynamic background worker" );
200
- }
201
- }
188
+ BackgroundWorker worker ;
189
+ BackgroundWorkerHandle * handle ;
190
+
191
+ if (pool -> nWorkers >= MtmMaxWorkers )
192
+ return ;
193
+
194
+ MemSet (& worker , 0 , sizeof (BackgroundWorker ));
195
+ worker .bgw_flags = BGWORKER_SHMEM_ACCESS | BGWORKER_BACKEND_DATABASE_CONNECTION ;
196
+ worker .bgw_start_time = BgWorkerStart_ConsistentState ;
197
+ worker .bgw_restart_time = MULTIMASTER_BGW_RESTART_TIMEOUT ;
198
+ worker .bgw_main_arg = PointerGetDatum (pool );
199
+ sprintf (worker .bgw_library_name , "multimaster" );
200
+ sprintf (worker .bgw_function_name , "BgwPoolDynamicWorkerMainLoop" );
201
+ snprintf (worker .bgw_name , BGW_MAXLEN , "%s-dynworker-%d" , pool -> poolName , (int ) pool -> nWorkers + 1 );
202
+
203
+ pool -> lastDynamicWorkerStartTime = MtmGetSystemTime ();
204
+ if (RegisterDynamicBackgroundWorker (& worker , & handle ))
205
+ {
206
+ pool -> bgwhandles [pool -> nWorkers ++ ] = handle ;
207
+ }
208
+ else
209
+ {
210
+ elog (WARNING , "Failed to start dynamic background worker" );
202
211
}
203
212
}
204
213
@@ -253,9 +262,29 @@ void BgwPoolExecute(BgwPool* pool, void* work, size_t size)
253
262
254
263
void BgwPoolStop (BgwPool * pool )
255
264
{
256
- // SpinLockAcquire(&pool->lock);
257
265
pool -> shutdown = true;
258
- // SpinLockRelease(&pool->lock);
259
266
PGSemaphoreUnlock (pool -> available );
260
267
PGSemaphoreUnlock (pool -> overflow );
261
268
}
269
+
270
+ /*
271
+ * Tell our lads to cancel currently active transactions.
272
+ */
273
+ void
274
+ BgwPoolCancel (BgwPool * pool )
275
+ {
276
+ int i ;
277
+
278
+ for (i = 0 ; i < pool -> nWorkers ; i ++ )
279
+ {
280
+ BgwHandleStatus status ;
281
+ pid_t pid ;
282
+
283
+ status = GetBackgroundWorkerPid (pool -> bgwhandles [i ], & pid );
284
+ if (status == BGWH_STARTED )
285
+ {
286
+ Assert (pid > 0 );
287
+ kill (pid , SIGINT );
288
+ }
289
+ }
290
+ }
0 commit comments