本文整理汇总了C++中ResetLatch函数的典型用法代码示例。如果您正苦于以下问题:C++ ResetLatch函数的具体用法?C++ ResetLatch怎么用?C++ ResetLatch使用的例子?那么, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了ResetLatch函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: ProcWaitForSignal
/*
* ProcWaitForSignal - wait for a signal from another backend.
*
* As this uses the generic process latch the caller has to be robust against
* unrelated wakeups: Always check that the desired state has occurred, and
* wait again if not.
*/
void
ProcWaitForSignal(void)
{
WaitLatch(MyLatch, WL_LATCH_SET, 0);
ResetLatch(MyLatch);
CHECK_FOR_INTERRUPTS();
}
示例2: hello_main
/*
* hello_main
*
* Main loop processing.
*/
void
hello_main(Datum main_arg)
{
/* Set up the sigterm signal before unblocking them */
pqsignal(SIGTERM, hello_sigterm);
/* We're now ready to receive signals */
BackgroundWorkerUnblockSignals();
while (!got_sigterm)
{
int rc;
/* Wait 10s */
rc = WaitLatch(&MyProc->procLatch,
WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
10000L,
PG_WAIT_EXTENSION);
ResetLatch(&MyProc->procLatch);
/* Emergency bailout if postmaster has died */
if (rc & WL_POSTMASTER_DEATH)
proc_exit(1);
elog(LOG, "Hello World!"); /* Say Hello to the world */
}
proc_exit(0);
}
示例3: shm_mq_receive_bytes
/*
* Wait until at least *nbytesp bytes are available to be read from the
* shared message queue, or until the buffer wraps around. If the queue is
* detached, returns SHM_MQ_DETACHED. If nowait is specified and a wait
* would be required, returns SHM_MQ_WOULD_BLOCK. Otherwise, *datap is set
* to the location at which data bytes can be read, *nbytesp is set to the
* number of bytes which can be read at that address, and the return value
* is SHM_MQ_SUCCESS.
*/
static shm_mq_result
shm_mq_receive_bytes(shm_mq *mq, Size bytes_needed, bool nowait,
Size *nbytesp, void **datap)
{
Size ringsize = mq->mq_ring_size;
uint64 used;
uint64 written;
for (;;)
{
Size offset;
bool detached;
/* Get bytes written, so we can compute what's available to read. */
written = shm_mq_get_bytes_written(mq, &detached);
used = written - mq->mq_bytes_read;
Assert(used <= ringsize);
offset = mq->mq_bytes_read % (uint64) ringsize;
/* If we have enough data or buffer has wrapped, we're done. */
if (used >= bytes_needed || offset + used >= ringsize)
{
*nbytesp = Min(used, ringsize - offset);
*datap = &mq->mq_ring[mq->mq_ring_offset + offset];
return SHM_MQ_SUCCESS;
}
/*
* Fall out before waiting if the queue has been detached.
*
* Note that we don't check for this until *after* considering
* whether the data already available is enough, since the
* receiver can finish receiving a message stored in the buffer
* even after the sender has detached.
*/
if (detached)
return SHM_MQ_DETACHED;
/* Skip manipulation of our latch if nowait = true. */
if (nowait)
return SHM_MQ_WOULD_BLOCK;
/*
* Wait for our latch to be set. It might already be set for
* some unrelated reason, but that'll just result in one extra
* trip through the loop. It's worth it to avoid resetting the
* latch at top of loop, because setting an already-set latch is
* much cheaper than setting one that has been reset.
*/
WaitLatch(&MyProc->procLatch, WL_LATCH_SET, 0);
/* An interrupt may have occurred while we were waiting. */
CHECK_FOR_INTERRUPTS();
/* Reset the latch so we don't spin. */
ResetLatch(&MyProc->procLatch);
}
}
示例4: wait_for_workers_to_become_ready
static void
wait_for_workers_to_become_ready(worker_state *wstate,
volatile test_shm_mq_header *hdr)
{
bool save_set_latch_on_sigusr1;
bool result = false;
save_set_latch_on_sigusr1 = set_latch_on_sigusr1;
set_latch_on_sigusr1 = true;
PG_TRY();
{
for (;;)
{
int workers_ready;
/* If all the workers are ready, we have succeeded. */
SpinLockAcquire(&hdr->mutex);
workers_ready = hdr->workers_ready;
SpinLockRelease(&hdr->mutex);
if (workers_ready >= wstate->nworkers)
{
result = true;
break;
}
/* If any workers (or the postmaster) have died, we have failed. */
if (!check_worker_status(wstate))
{
result = false;
break;
}
/* Wait to be signalled. */
WaitLatch(MyLatch, WL_LATCH_SET, 0);
/* An interrupt may have occurred while we were waiting. */
CHECK_FOR_INTERRUPTS();
/* Reset the latch so we don't spin. */
ResetLatch(MyLatch);
}
}
PG_CATCH();
{
set_latch_on_sigusr1 = save_set_latch_on_sigusr1;
PG_RE_THROW();
}
PG_END_TRY();
if (!result)
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_RESOURCES),
errmsg("one or more background workers failed to start")));
}
示例5: WaitForReplicationWorkerAttach
/*
* Wait for a background worker to start up and attach to the shmem context.
*
* This is only needed for cleaning up the shared memory in case the worker
* fails to attach.
*/
static void
WaitForReplicationWorkerAttach(LogicalRepWorker *worker,
uint16 generation,
BackgroundWorkerHandle *handle)
{
BgwHandleStatus status;
int rc;
for (;;)
{
pid_t pid;
CHECK_FOR_INTERRUPTS();
LWLockAcquire(LogicalRepWorkerLock, LW_SHARED);
/* Worker either died or has started; no need to do anything. */
if (!worker->in_use || worker->proc)
{
LWLockRelease(LogicalRepWorkerLock);
return;
}
LWLockRelease(LogicalRepWorkerLock);
/* Check if worker has died before attaching, and clean up after it. */
status = GetBackgroundWorkerPid(handle, &pid);
if (status == BGWH_STOPPED)
{
LWLockAcquire(LogicalRepWorkerLock, LW_EXCLUSIVE);
/* Ensure that this was indeed the worker we waited for. */
if (generation == worker->generation)
logicalrep_worker_cleanup(worker);
LWLockRelease(LogicalRepWorkerLock);
return;
}
/*
* We need timeout because we generally don't get notified via latch
* about the worker attach. But we don't expect to have to wait long.
*/
rc = WaitLatch(MyLatch,
WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
10L, WAIT_EVENT_BGWORKER_STARTUP);
if (rc & WL_LATCH_SET)
{
ResetLatch(MyLatch);
CHECK_FOR_INTERRUPTS();
}
}
return;
}
示例6: secure_read
/*
* Read data from a secure connection.
*/
ssize_t
secure_read(Port *port, void *ptr, size_t len)
{
ssize_t n;
int waitfor;
retry:
#ifdef USE_SSL
waitfor = 0;
if (port->ssl_in_use)
{
n = be_tls_read(port, ptr, len, &waitfor);
}
else
#endif
{
n = secure_raw_read(port, ptr, len);
waitfor = WL_SOCKET_READABLE;
}
/* In blocking mode, wait until the socket is ready */
if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
{
int w;
Assert(waitfor);
w = WaitLatchOrSocket(MyLatch,
WL_LATCH_SET | waitfor,
port->sock, 0);
/* Handle interrupt. */
if (w & WL_LATCH_SET)
{
ResetLatch(MyLatch);
ProcessClientReadInterrupt(true);
/*
* We'll retry the read. Most likely it will return immediately
* because there's still no data available, and we'll wait
* for the socket to become ready again.
*/
}
goto retry;
}
/*
* Process interrupts that happened while (or before) receiving. Note that
* we signal that we're not blocking, which will prevent some types of
* interrupts from being processed.
*/
ProcessClientReadInterrupt(false);
return n;
}
示例7: pg_sleep
/*
* pg_sleep - delay for N seconds
*/
Datum
pg_sleep(PG_FUNCTION_ARGS)
{
float8 secs = PG_GETARG_FLOAT8(0);
float8 endtime;
/*
* We sleep using WaitLatch, to ensure that we'll wake up promptly if an
* important signal (such as SIGALRM or SIGINT) arrives. Because
* WaitLatch's upper limit of delay is INT_MAX milliseconds, and the user
* might ask for more than that, we sleep for at most 10 minutes and then
* loop.
*
* By computing the intended stop time initially, we avoid accumulation of
* extra delay across multiple sleeps. This also ensures we won't delay
* less than the specified time when WaitLatch is terminated early by a
* non-query-canceling signal such as SIGHUP.
*/
#ifdef HAVE_INT64_TIMESTAMP
#define GetNowFloat() ((float8) GetCurrentTimestamp() / 1000000.0)
#else
#define GetNowFloat() GetCurrentTimestamp()
#endif
endtime = GetNowFloat() + secs;
for (;;)
{
float8 delay;
long delay_ms;
CHECK_FOR_INTERRUPTS();
delay = endtime - GetNowFloat();
if (delay >= 600.0)
delay_ms = 600000;
else if (delay > 0.0)
delay_ms = (long) ceil(delay * 1000.0);
else
break;
(void) WaitLatch(MyLatch,
WL_LATCH_SET | WL_TIMEOUT,
delay_ms,
WAIT_EVENT_PG_SLEEP);
ResetLatch(MyLatch);
}
PG_RETURN_VOID();
}
示例8: BufferSaverMain
static void
BufferSaverMain(Datum main_arg)
{
WorkerCommon();
/*
* Main loop: do this until the SIGTERM handler tells us to terminate
*/
while (!got_sigterm)
{
int rc;
ResetLatch(&MyProc->procLatch);
/*
* Wait on the process latch, which sleeps as necessary, but is awakened
* if postmaster dies. This way the background process goes away
* immediately in case of an emergency.
*/
rc = WaitLatch(&MyProc->procLatch,
WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
10 * 1000L);
/* emergency bailout if postmaster has died */
if (rc & WL_POSTMASTER_DEATH)
proc_exit(1);
/*
* In case of a SIGHUP, just reload the configuration.
*/
if (got_sighup)
{
got_sighup = false;
ProcessConfigFile(PGC_SIGHUP);
}
}
/*
* We recieved the SIGTERM; Shutdown is in progress, so save the
* shared-buffer contents.
*/
/* Save the buffers only if the extension is enabled. */
if (guc_enabled)
SaveBuffers();
/*
* The worker exits here. A proc_exit(0) is not necessary, we'll let the
* caller do that.
*/
}
示例9: shm_mq_wait_internal
/*
* This is used when a process is waiting for its counterpart to attach to the
* queue. We exit when the other process attaches as expected, or, if
* handle != NULL, when the referenced background process or the postmaster
* dies. Note that if handle == NULL, and the process fails to attach, we'll
* potentially get stuck here forever waiting for a process that may never
* start. We do check for interrupts, though.
*
* ptr is a pointer to the memory address that we're expecting to become
* non-NULL when our counterpart attaches to the queue.
*/
static bool
shm_mq_wait_internal(volatile shm_mq *mq, PGPROC *volatile * ptr,
BackgroundWorkerHandle *handle)
{
bool result = false;
for (;;)
{
BgwHandleStatus status;
pid_t pid;
bool detached;
/* Acquire the lock just long enough to check the pointer. */
SpinLockAcquire(&mq->mq_mutex);
detached = mq->mq_detached;
result = (*ptr != NULL);
SpinLockRelease(&mq->mq_mutex);
/* Fail if detached; else succeed if initialized. */
if (detached)
{
result = false;
break;
}
if (result)
break;
if (handle != NULL)
{
/* Check for unexpected worker death. */
status = GetBackgroundWorkerPid(handle, &pid);
if (status != BGWH_STARTED && status != BGWH_NOT_YET_STARTED)
{
result = false;
break;
}
}
/* Wait to be signalled. */
WaitLatch(MyLatch, WL_LATCH_SET, 0);
/* An interrupt may have occurred while we were waiting. */
CHECK_FOR_INTERRUPTS();
/* Reset the latch so we don't spin. */
ResetLatch(MyLatch);
}
return result;
}
示例10: ConditionVariablePrepareToSleep
/*
* Prepare to wait on a given condition variable.
*
* This can optionally be called before entering a test/sleep loop.
* Doing so is more efficient if we'll need to sleep at least once.
* However, if the first test of the exit condition is likely to succeed,
* it's more efficient to omit the ConditionVariablePrepareToSleep call.
* See comments in ConditionVariableSleep for more detail.
*
* Caution: "before entering the loop" means you *must* test the exit
* condition between calling ConditionVariablePrepareToSleep and calling
* ConditionVariableSleep. If that is inconvenient, omit calling
* ConditionVariablePrepareToSleep.
*/
void
ConditionVariablePrepareToSleep(ConditionVariable *cv)
{
int pgprocno = MyProc->pgprocno;
/*
* If first time through in this process, create a WaitEventSet, which
* we'll reuse for all condition variable sleeps.
*/
if (cv_wait_event_set == NULL)
{
WaitEventSet *new_event_set;
new_event_set = CreateWaitEventSet(TopMemoryContext, 2);
AddWaitEventToSet(new_event_set, WL_LATCH_SET, PGINVALID_SOCKET,
MyLatch, NULL);
AddWaitEventToSet(new_event_set, WL_EXIT_ON_PM_DEATH, PGINVALID_SOCKET,
NULL, NULL);
/* Don't set cv_wait_event_set until we have a correct WES. */
cv_wait_event_set = new_event_set;
}
/*
* If some other sleep is already prepared, cancel it; this is necessary
* because we have just one static variable tracking the prepared sleep,
* and also only one cvWaitLink in our PGPROC. It's okay to do this
* because whenever control does return to the other test-and-sleep loop,
* its ConditionVariableSleep call will just re-establish that sleep as
* the prepared one.
*/
if (cv_sleep_target != NULL)
ConditionVariableCancelSleep();
/* Record the condition variable on which we will sleep. */
cv_sleep_target = cv;
/*
* Reset my latch before adding myself to the queue, to ensure that we
* don't miss a wakeup that occurs immediately.
*/
ResetLatch(MyLatch);
/* Add myself to the wait queue. */
SpinLockAcquire(&cv->mutex);
proclist_push_tail(&cv->wakeup, pgprocno, cvWaitLink);
SpinLockRelease(&cv->mutex);
}
示例11: wait_for_worker_state_change
/*
* Wait until the apply worker changes the state of our synchronization
* worker to the expected one.
*
* Used when transitioning from SYNCWAIT state to CATCHUP.
*
* Returns false if the apply worker has disappeared.
*/
static bool
wait_for_worker_state_change(char expected_state)
{
int rc;
for (;;)
{
LogicalRepWorker *worker;
CHECK_FOR_INTERRUPTS();
/*
* Done if already in correct state. (We assume this fetch is atomic
* enough to not give a misleading answer if we do it with no lock.)
*/
if (MyLogicalRepWorker->relstate == expected_state)
return true;
/*
* Bail out if the apply worker has died, else signal it we're
* waiting.
*/
LWLockAcquire(LogicalRepWorkerLock, LW_SHARED);
worker = logicalrep_worker_find(MyLogicalRepWorker->subid,
InvalidOid, false);
if (worker && worker->proc)
logicalrep_worker_wakeup_ptr(worker);
LWLockRelease(LogicalRepWorkerLock);
if (!worker)
break;
/*
* Wait. We expect to get a latch signal back from the apply worker,
* but use a timeout in case it dies without sending one.
*/
rc = WaitLatch(MyLatch,
WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
1000L, WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE);
if (rc & WL_LATCH_SET)
ResetLatch(MyLatch);
}
return false;
}
示例12: wait_for_relation_state_change
/*
* Wait until the relation synchronization state is set in the catalog to the
* expected one.
*
* Used when transitioning from CATCHUP state to SYNCDONE.
*
* Returns false if the synchronization worker has disappeared or the table state
* has been reset.
*/
static bool
wait_for_relation_state_change(Oid relid, char expected_state)
{
char state;
for (;;)
{
LogicalRepWorker *worker;
XLogRecPtr statelsn;
CHECK_FOR_INTERRUPTS();
/* XXX use cache invalidation here to improve performance? */
PushActiveSnapshot(GetLatestSnapshot());
state = GetSubscriptionRelState(MyLogicalRepWorker->subid,
relid, &statelsn, true);
PopActiveSnapshot();
if (state == SUBREL_STATE_UNKNOWN)
return false;
if (state == expected_state)
return true;
/* Check if the sync worker is still running and bail if not. */
LWLockAcquire(LogicalRepWorkerLock, LW_SHARED);
/* Check if the opposite worker is still running and bail if not. */
worker = logicalrep_worker_find(MyLogicalRepWorker->subid,
am_tablesync_worker() ? InvalidOid : relid,
false);
LWLockRelease(LogicalRepWorkerLock);
if (!worker)
return false;
(void) WaitLatch(MyLatch,
WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
1000L, WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE);
ResetLatch(MyLatch);
}
return false;
}
示例13: config_log_main
static void
config_log_main(Datum main_arg)
{
config_log_objects *objects;
pqsignal(SIGTERM, config_log_sigterm);
pqsignal(SIGHUP, config_log_sighup);
/* We're now ready to receive signals */
BackgroundWorkerUnblockSignals();
/* Connect to database */
BackgroundWorkerInitializeConnection(config_log_database, NULL);
/* Verify expected objects exist */
objects = initialize_objects();
while (!got_sigterm)
{
int rc;
rc = WaitLatch(&MyProc->procLatch,
WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
100000L);
ResetLatch(&MyProc->procLatch);
/* emergency bailout if postmaster has died */
if (rc & WL_POSTMASTER_DEATH)
proc_exit(1);
/*
* In case of a SIGHUP, just reload the configuration.
*/
if (got_sighup)
{
got_sighup = false;
ProcessConfigFile(PGC_SIGHUP);
execute_pg_settings_logger(objects);
}
}
proc_exit(0);
}
示例14: SegmentInfoSenderLoop
/**
* Main loop of the sender process. It wakes up every
* gp_perfmon_segment_interval ms to send segment
* information to perfmon
*/
static void
SegmentInfoSenderLoop(void)
{
int rc;
int counter;
for (counter = 0;; counter += SEGMENT_INFO_LOOP_SLEEP_MS)
{
CHECK_FOR_INTERRUPTS();
if (senderShutdownRequested)
{
break;
}
/* no need to live on if postmaster has died */
if (!PostmasterIsAlive())
exit(1);
if (cluster_state_collect_hook)
cluster_state_collect_hook();
if (gp_enable_gpperfmon && counter >= gp_perfmon_segment_interval)
{
SegmentInfoSender();
counter = 0;
}
/* Sleep a while. */
rc = WaitLatch(&MyProc->procLatch,
WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
SEGMENT_INFO_LOOP_SLEEP_MS);
ResetLatch(&MyProc->procLatch);
/* emergency bailout if postmaster has died */
if (rc & WL_POSTMASTER_DEATH)
proc_exit(1);
} /* end server loop */
return;
}
示例15: pgfdw_get_result
/*
* Wait for the result from a prior asynchronous execution function call.
*
* This function offers quick responsiveness by checking for any interruptions.
*
* This function emulates the PQexec()'s behavior of returning the last result
* when there are many.
*
* Caller is responsible for the error handling on the result.
*/
PGresult *
pgfdw_get_result(PGconn *conn, const char *query)
{
PGresult *last_res = NULL;
for (;;)
{
PGresult *res;
while (PQisBusy(conn))
{
int wc;
/* Sleep until there's something to do */
wc = WaitLatchOrSocket(MyLatch,
WL_LATCH_SET | WL_SOCKET_READABLE,
PQsocket(conn),
-1L, PG_WAIT_EXTENSION);
ResetLatch(MyLatch);
CHECK_FOR_INTERRUPTS();
/* Data available in socket */
if (wc & WL_SOCKET_READABLE)
{
if (!PQconsumeInput(conn))
pgfdw_report_error(ERROR, NULL, conn, false, query);
}
}
res = PQgetResult(conn);
if (res == NULL)
break; /* query is complete */
PQclear(last_res);
last_res = res;
}
return last_res;
}