-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathmain_c.c
100 lines (83 loc) · 2.08 KB
/
main_c.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/* PostgreSQL related headers */
#include "postgres.h"
#include "pgstat.h"
#include "postmaster/bgworker.h"
#include "storage/ipc.h"
#include "storage/latch.h"
#include "storage/proc.h"
#include "utils/elog.h"
#include "fmgr.h"
/* Go related headers */
#include "_cgo_export.h"
PG_MODULE_MAGIC;
/* Entry point of library loading */
void _PG_init(void);
/* Main loop of process */
void background_main(Datum main_arg) pg_attribute_noreturn();
/* Wrappers to using in CGO */
void elog_log(char *string) {
elog(LOG, string, "");
}
int wait_latch(long miliseconds) {
return WaitLatch(&MyProc->procLatch,
WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
miliseconds,
PG_WAIT_EXTENSION);
}
void reset_latch(void) {
ResetLatch(&MyProc->procLatch);
}
int postmaster_is_dead(int rc) {
return (rc & WL_POSTMASTER_DEATH);
}
/* Signal handling */
static volatile sig_atomic_t got_sigterm = false;
int get_got_sigterm() {
return (got_sigterm == true);
}
/*
* background_sigterm
*
* SIGTERM handler.
*/
static void
background_sigterm(SIGNAL_ARGS)
{
int save_errno = errno;
got_sigterm = true;
if (MyProc)
SetLatch(&MyProc->procLatch);
errno = save_errno;
}
/*
* background_main
*
* Main loop processing.
*/
void
background_main(Datum main_arg)
{
/* Set up the sigterm signal before unblocking them */
pqsignal(SIGTERM, background_sigterm);
/* We're now ready to receive signals */
BackgroundWorkerUnblockSignals();
/* Main loop in Golang */
if (BackgroundWorkerMain()) {
proc_exit(1);
}
proc_exit(0);
}
void _PG_init(void) {
BackgroundWorker worker;
/* Register the worker processes */
MemSet(&worker, 0, sizeof(BackgroundWorker));
worker.bgw_flags = BGWORKER_SHMEM_ACCESS;
worker.bgw_start_time = BgWorkerStart_RecoveryFinished;
snprintf(worker.bgw_library_name, BGW_MAXLEN, "go_background_worker");
snprintf(worker.bgw_function_name, BGW_MAXLEN, "background_main");
snprintf(worker.bgw_name, BGW_MAXLEN, "GoBackgroundWorker");
worker.bgw_restart_time = BGW_NEVER_RESTART;
worker.bgw_main_arg = (Datum) 0;
worker.bgw_notify_pid = 0;
RegisterBackgroundWorker(&worker);
}