@@ -39,10 +39,13 @@ BgwShutdownHandler(int sig)
39
39
die (sig );
40
40
}
41
41
42
- static void BgwPoolMainLoop (BgwPool * pool )
42
+ static void
43
+ BgwPoolMainLoop (BgwPool * pool )
43
44
{
44
- int size ;
45
- void * work ;
45
+ int size ;
46
+ void * work ;
47
+ size_t payload = sizeof (MtmReceiverContext ) + sizeof (size_t );
48
+ MtmReceiverContext ctx ;
46
49
static PortalData fakePortal ;
47
50
48
51
mtm_log (BgwPoolEvent , "Start background worker %d, shutdown=%d" , MyProcPid , pool -> shutdown );
@@ -56,61 +59,72 @@ static void BgwPoolMainLoop(BgwPool* pool)
56
59
pqsignal (SIGTERM , BgwShutdownHandler );
57
60
pqsignal (SIGHUP , PostgresSigHupHandler );
58
61
59
- BackgroundWorkerUnblockSignals ();
62
+ BackgroundWorkerUnblockSignals ();
60
63
BackgroundWorkerInitializeConnection (pool -> dbname , pool -> dbuser , 0 );
61
64
ActivePortal = & fakePortal ;
62
65
ActivePortal -> status = PORTAL_ACTIVE ;
63
66
ActivePortal -> sourceText = "" ;
64
67
65
- while (true) {
68
+ while (true)
69
+ {
66
70
if (ConfigReloadPending )
67
71
{
68
72
ConfigReloadPending = false;
69
73
ProcessConfigFile (PGC_SIGHUP );
70
74
}
71
75
72
76
PGSemaphoreLock (pool -> available );
73
- SpinLockAcquire (& pool -> lock );
74
- if (pool -> shutdown ) {
77
+ SpinLockAcquire (& pool -> lock );
78
+ if (pool -> shutdown )
79
+ {
75
80
PGSemaphoreUnlock (pool -> available );
76
81
break ;
77
82
}
78
- size = * (int * )& pool -> queue [pool -> head ];
79
- Assert (size < pool -> size );
80
- work = palloc (size );
81
- pool -> pending -= 1 ;
82
- pool -> active += 1 ;
83
- if (pool -> lastPeakTime == 0 && pool -> active == pool -> nWorkers && pool -> pending != 0 ) {
83
+ size = * (int * ) & pool -> queue [pool -> head ];
84
+ ctx = * (MtmReceiverContext * ) & pool -> queue [pool -> head + sizeof (size_t )];
85
+
86
+ Assert (size < pool -> size );
87
+ work = palloc (size );
88
+ pool -> pending -= 1 ;
89
+ pool -> active += 1 ;
90
+ if (pool -> lastPeakTime == 0 && pool -> active == pool -> nWorkers && pool -> pending != 0 )
84
91
pool -> lastPeakTime = MtmGetSystemTime ();
92
+
93
+ if (pool -> head + size + payload > pool -> size )
94
+ {
95
+ memcpy (work , pool -> queue , size );
96
+ pool -> head = INTALIGN (size );
85
97
}
86
- if ( pool -> head + size + 4 > pool -> size ) {
87
- memcpy ( work , pool -> queue , size );
88
- pool -> head = INTALIGN ( size );
89
- } else {
90
- memcpy ( work , & pool -> queue [ pool -> head + 4 ], size );
91
- pool -> head += 4 + INTALIGN ( size );
92
- }
93
- if ( pool -> size == pool -> head ) {
94
- pool -> head = 0 ;
95
- }
96
- if ( pool -> producerBlocked ) {
97
- pool -> producerBlocked = false;
98
+ else
99
+ {
100
+ memcpy ( work , & pool -> queue [ pool -> head + payload ], size );
101
+ pool -> head += payload + INTALIGN ( size );
102
+ }
103
+
104
+ if ( pool -> size == pool -> head )
105
+ pool -> head = 0 ;
106
+
107
+ if ( pool -> producerBlocked )
108
+ {
109
+ pool -> producerBlocked = false;
98
110
PGSemaphoreUnlock (pool -> overflow );
99
111
pool -> lastPeakTime = 0 ;
100
- }
101
- SpinLockRelease (& pool -> lock );
112
+ }
113
+
114
+ SpinLockRelease (& pool -> lock );
102
115
103
116
/* Ignore cancel that arrived before we started current command */
104
117
QueryCancelPending = false;
105
118
106
- pool -> executor (work , size , NULL );
119
+ pool -> executor (work , size , & ctx );
107
120
pfree (work );
108
121
109
- SpinLockAcquire (& pool -> lock );
110
- pool -> active -= 1 ;
122
+ SpinLockAcquire (& pool -> lock );
123
+ pool -> active -= 1 ;
111
124
pool -> lastPeakTime = 0 ;
112
- SpinLockRelease (& pool -> lock );
113
- }
125
+ SpinLockRelease (& pool -> lock );
126
+ }
127
+
114
128
SpinLockRelease (& pool -> lock );
115
129
mtm_log (BgwPoolEvent , "Shutdown background worker %d" , MyProcPid );
116
130
}
@@ -211,9 +225,13 @@ static void BgwStartExtraWorker(BgwPool* pool)
211
225
}
212
226
}
213
227
214
- void BgwPoolExecute (BgwPool * pool , void * work , size_t size )
228
+ void
229
+ BgwPoolExecute (BgwPool * pool , void * work , size_t size , MtmReceiverContext * ctx )
215
230
{
216
- if (size + 4 > pool -> size ) {
231
+ size_t payload = sizeof (MtmReceiverContext ) + sizeof (size_t );
232
+
233
+ if (size + payload > pool -> size )
234
+ {
217
235
/*
218
236
* Size of work is larger than size of shared buffer:
219
237
* run it immediately
@@ -222,42 +240,52 @@ void BgwPoolExecute(BgwPool* pool, void* work, size_t size)
222
240
return ;
223
241
}
224
242
225
- SpinLockAcquire (& pool -> lock );
226
- while (!pool -> shutdown ) {
227
- if ((pool -> head <= pool -> tail && pool -> size - pool -> tail < size + 4 && pool -> head < size )
228
- || (pool -> head > pool -> tail && pool -> head - pool -> tail < size + 4 ))
229
- {
230
- if (pool -> lastPeakTime == 0 ) {
243
+ SpinLockAcquire (& pool -> lock );
244
+ while (!pool -> shutdown )
245
+ {
246
+ if ((pool -> head <= pool -> tail && pool -> size - pool -> tail < size + payload && pool -> head < size )
247
+ || (pool -> head > pool -> tail && pool -> head - pool -> tail < size + payload ))
248
+ {
249
+ if (pool -> lastPeakTime == 0 )
231
250
pool -> lastPeakTime = MtmGetSystemTime ();
232
- }
251
+
233
252
pool -> producerBlocked = true;
234
- SpinLockRelease (& pool -> lock );
253
+ SpinLockRelease (& pool -> lock );
235
254
PGSemaphoreLock (pool -> overflow );
236
- SpinLockAcquire (& pool -> lock );
237
- } else {
238
- pool -> pending += 1 ;
239
- if (pool -> active + pool -> pending > pool -> nWorkers ) {
240
- BgwStartExtraWorker (pool );
241
- }
242
- if (pool -> lastPeakTime == 0 && pool -> active == pool -> nWorkers && pool -> pending != 0 ) {
255
+ SpinLockAcquire (& pool -> lock );
256
+ }
257
+ else
258
+ {
259
+ pool -> pending += 1 ;
260
+
261
+ if (pool -> active + pool -> pending > pool -> nWorkers )
262
+ BgwStartExtraWorker (pool );
263
+
264
+ if (pool -> lastPeakTime == 0 && pool -> active == pool -> nWorkers && pool -> pending != 0 )
243
265
pool -> lastPeakTime = MtmGetSystemTime ();
266
+
267
+ * (int * )& pool -> queue [pool -> tail ] = size ;
268
+ * (MtmReceiverContext * )& pool -> queue [pool -> tail + sizeof (size_t )] = * ctx ;
269
+
270
+ if (pool -> size - pool -> tail >= size + payload )
271
+ {
272
+ memcpy (& pool -> queue [pool -> tail + payload ], work , size );
273
+ pool -> tail += payload + INTALIGN (size );
274
+ }
275
+ else
276
+ {
277
+ memcpy (pool -> queue , work , size );
278
+ pool -> tail = INTALIGN (size );
244
279
}
245
- * (int * )& pool -> queue [pool -> tail ] = size ;
246
- if (pool -> size - pool -> tail >= size + 4 ) {
247
- memcpy (& pool -> queue [pool -> tail + 4 ], work , size );
248
- pool -> tail += 4 + INTALIGN (size );
249
- } else {
250
- memcpy (pool -> queue , work , size );
251
- pool -> tail = INTALIGN (size );
252
- }
253
- if (pool -> tail == pool -> size ) {
254
- pool -> tail = 0 ;
255
- }
280
+
281
+ if (pool -> tail == pool -> size )
282
+ pool -> tail = 0 ;
283
+
256
284
PGSemaphoreUnlock (pool -> available );
257
- break ;
258
- }
259
- }
260
- SpinLockRelease (& pool -> lock );
285
+ break ;
286
+ }
287
+ }
288
+ SpinLockRelease (& pool -> lock );
261
289
}
262
290
263
291
void BgwPoolStop (BgwPool * pool )
0 commit comments