PostgreSQL Source Code: src/include/storage/waiteventset.h File Reference (original) (raw)

Go to the source code of this file.

Macros
#define WL_LATCH_SET (1 << 0)
#define WL_SOCKET_READABLE (1 << 1)
#define WL_SOCKET_WRITEABLE (1 << 2)
#define WL_TIMEOUT (1 << 3) /* not for WaitEventSetWait() */
#define WL_POSTMASTER_DEATH (1 << 4)
#define WL_EXIT_ON_PM_DEATH (1 << 5)
#define WL_SOCKET_CONNECTED WL_SOCKET_WRITEABLE
#define WL_SOCKET_CLOSED (1 << 7)
#define WL_SOCKET_ACCEPT WL_SOCKET_READABLE
#define WL_SOCKET_MASK
Functions
void InitializeWaitEventSupport (void)
WaitEventSet * CreateWaitEventSet (ResourceOwner resowner, int nevents)
void FreeWaitEventSet (WaitEventSet *set)
void FreeWaitEventSetAfterFork (WaitEventSet *set)
int AddWaitEventToSet (WaitEventSet *set, uint32 events, pgsocket fd, struct Latch *latch, void *user_data)
void ModifyWaitEvent (WaitEventSet *set, int pos, uint32 events, struct Latch *latch)
int WaitEventSetWait (WaitEventSet *set, long timeout, WaitEvent *occurred_events, int nevents, uint32 wait_event_info)
int GetNumRegisteredWaitEvents (WaitEventSet *set)
bool WaitEventSetCanReportClosed (void)
void WakeupMyProc (void)
void WakeupOtherProc (int pid)

WL_EXIT_ON_PM_DEATH

#define WL_EXIT_ON_PM_DEATH (1 << 5)

WL_LATCH_SET

#define WL_LATCH_SET (1 << 0)

WL_POSTMASTER_DEATH

#define WL_POSTMASTER_DEATH (1 << 4)

WL_SOCKET_ACCEPT

WL_SOCKET_CLOSED

#define WL_SOCKET_CLOSED (1 << 7)

WL_SOCKET_CONNECTED

WL_SOCKET_MASK

Value:

WL_SOCKET_WRITEABLE | \

WL_SOCKET_CONNECTED | \

WL_SOCKET_ACCEPT | \

WL_SOCKET_CLOSED)

#define WL_SOCKET_READABLE

Definition at line 53 of file waiteventset.h.

WL_SOCKET_READABLE

#define WL_SOCKET_READABLE (1 << 1)

WL_SOCKET_WRITEABLE

#define WL_SOCKET_WRITEABLE (1 << 2)

WL_TIMEOUT

WaitEvent

AddWaitEventToSet()

Definition at line 569 of file waiteventset.c.

571{

573

574

576

578 {

581 }

582

583 if (latch)

584 {

586 elog(ERROR, "cannot wait on a latch owned by another process");

588 elog(ERROR, "cannot wait on more than one latch");

590 elog(ERROR, "latch events only support being set");

591 }

592 else

593 {

595 elog(ERROR, "cannot wait on latch without a specified latch");

596 }

597

598

600 elog(ERROR, "cannot wait on socket event without a socket");

601

604 event->fd = fd;

605 event->events = events;

606 event->user_data = user_data;

607#ifdef WIN32

608 event->reset = false;

609#endif

610

612 {

613 set->latch = latch;

615#if defined(WAIT_USE_SELF_PIPE)

617#elif defined(WAIT_USE_SIGNALFD)

618 event->fd = signal_fd;

619#else

621#ifdef WAIT_USE_EPOLL

622 return event->pos;

623#endif

624#endif

625 }

627 {

628#ifndef WIN32

630#endif

631 }

632

633

634#if defined(WAIT_USE_EPOLL)

635 WaitEventAdjustEpoll(set, event, EPOLL_CTL_ADD);

636#elif defined(WAIT_USE_KQUEUE)

637 WaitEventAdjustKqueue(set, event, 0);

638#elif defined(WAIT_USE_POLL)

640#elif defined(WAIT_USE_WIN32)

641 WaitEventAdjustWin32(set, event);

642#endif

643

644 return event->pos;

645}

Assert(PointerIsAligned(start, uint64))

int postmaster_alive_fds[2]

#define POSTMASTER_FD_WATCH

static int fd(const char *x, int i)

bool exit_on_postmaster_death

static int selfpipe_readfd

static void WaitEventAdjustPoll(WaitEventSet *set, WaitEvent *event)

#define WL_EXIT_ON_PM_DEATH

#define WL_POSTMASTER_DEATH

References Assert(), elog, ERROR, WaitEventSet::events, WaitEventSet::exit_on_postmaster_death, fd(), WaitEventSet::latch, WaitEventSet::latch_pos, MyProcPid, WaitEventSet::nevents, WaitEventSet::nevents_space, Latch::owner_pid, PGINVALID_SOCKET, WaitEvent::pos, postmaster_alive_fds, POSTMASTER_FD_WATCH, selfpipe_readfd, WaitEventAdjustPoll(), WL_EXIT_ON_PM_DEATH, WL_LATCH_SET, WL_POSTMASTER_DEATH, and WL_SOCKET_MASK.

Referenced by ConfigurePostmasterWaitSet(), ExecAppendAsyncEventWait(), InitializeLatchWaitSet(), postgresForeignAsyncConfigureWait(), pq_init(), SysLoggerMain(), and WaitLatchOrSocket().

CreateWaitEventSet()

Definition at line 363 of file waiteventset.c.

364{

368

369

370

371

372

373

374

377

378#if defined(WAIT_USE_EPOLL)

379 sz += MAXALIGN(sizeof(struct epoll_event) * nevents);

380#elif defined(WAIT_USE_KQUEUE)

381 sz += MAXALIGN(sizeof(struct kevent) * nevents);

382#elif defined(WAIT_USE_POLL)

383 sz += MAXALIGN(sizeof(struct pollfd) * nevents);

384#elif defined(WAIT_USE_WIN32)

385

386 sz += MAXALIGN(sizeof(HANDLE) * (nevents + 1));

387#endif

388

389 if (resowner != NULL)

391

393

396

399

400#if defined(WAIT_USE_EPOLL)

401 set->epoll_ret_events = (struct epoll_event *) data;

402 data += MAXALIGN(sizeof(struct epoll_event) * nevents);

403#elif defined(WAIT_USE_KQUEUE)

404 set->kqueue_ret_events = (struct kevent *) data;

405 data += MAXALIGN(sizeof(struct kevent) * nevents);

406#elif defined(WAIT_USE_POLL)

408 data += MAXALIGN(sizeof(struct pollfd) * nevents);

409#elif defined(WAIT_USE_WIN32)

410 set->handles = (HANDLE) data;

412#endif

413

414 set->latch = NULL;

417

418 if (resowner != NULL)

419 {

421 set->owner = resowner;

422 }

423

424#if defined(WAIT_USE_EPOLL)

426 elog(ERROR, "AcquireExternalFD, for epoll_create1, failed: %m");

427 set->epoll_fd = epoll_create1(EPOLL_CLOEXEC);

428 if (set->epoll_fd < 0)

429 {

431 elog(ERROR, "epoll_create1 failed: %m");

432 }

433#elif defined(WAIT_USE_KQUEUE)

435 elog(ERROR, "AcquireExternalFD, for kqueue, failed: %m");

436 set->kqueue_fd = kqueue();

437 if (set->kqueue_fd < 0)

438 {

440 elog(ERROR, "kqueue failed: %m");

441 }

442 if (fcntl(set->kqueue_fd, F_SETFD, FD_CLOEXEC) == -1)

443 {

444 int save_errno = errno;

445

446 close(set->kqueue_fd);

448 errno = save_errno;

449 elog(ERROR, "fcntl(F_SETFD) failed on kqueue descriptor: %m");

450 }

451 set->report_postmaster_not_running = false;

452#elif defined(WAIT_USE_WIN32)

453

454

455

456

457

458

459

460

461

462

465#endif

466

467 return set;

468}

#define StaticAssertStmt(condition, errmessage)

void ReleaseExternalFD(void)

bool AcquireExternalFD(void)

void * MemoryContextAllocZero(MemoryContext context, Size size)

MemoryContext TopMemoryContext

void ResourceOwnerEnlarge(ResourceOwner owner)

HANDLE pgwin32_signal_event

static void ResourceOwnerRememberWaitEventSet(ResourceOwner owner, WaitEventSet *set)

References AcquireExternalFD(), close, data, elog, ERROR, WaitEventSet::events, WaitEventSet::exit_on_postmaster_death, WaitEventSet::latch, MAXALIGN, MemoryContextAllocZero(), WaitEventSet::nevents_space, WaitEventSet::owner, pgwin32_signal_event, WaitEventSet::pollfds, ReleaseExternalFD(), ResourceOwnerEnlarge(), ResourceOwnerRememberWaitEventSet(), StaticAssertStmt, and TopMemoryContext.

Referenced by ConfigurePostmasterWaitSet(), ExecAppendAsyncEventWait(), InitializeLatchWaitSet(), pq_init(), SysLoggerMain(), and WaitLatchOrSocket().

FreeWaitEventSet()

Definition at line 480 of file waiteventset.c.

481{

483 {

485 set->owner = NULL;

486 }

487

488#if defined(WAIT_USE_EPOLL)

489 close(set->epoll_fd);

491#elif defined(WAIT_USE_KQUEUE)

492 close(set->kqueue_fd);

494#elif defined(WAIT_USE_WIN32)

497 cur_event++)

498 {

500 {

501

502 }

504 {

505

506 }

507 else

508 {

509

510 WSAEventSelect(cur_event->fd, NULL, 0);

511 WSACloseEvent(set->handles[cur_event->pos + 1]);

512 }

513 }

514#endif

515

517}

void pfree(void *pointer)

static void ResourceOwnerForgetWaitEventSet(ResourceOwner owner, WaitEventSet *set)

References close, WaitEventSet::events, WaitEventSet::nevents, WaitEventSet::owner, pfree(), ReleaseExternalFD(), ResourceOwnerForgetWaitEventSet(), WL_LATCH_SET, and WL_POSTMASTER_DEATH.

Referenced by ConfigurePostmasterWaitSet(), ExecAppendAsyncEventWait(), ResOwnerReleaseWaitEventSet(), and WaitLatchOrSocket().

FreeWaitEventSetAfterFork()

GetNumRegisteredWaitEvents()

InitializeWaitEventSupport()

void InitializeWaitEventSupport ( void )

Definition at line 240 of file waiteventset.c.

241{

242#if defined(WAIT_USE_SELF_PIPE)

243 int pipefd[2];

244

246 {

247

248

249

250

251

252

254 {

255

257

260

263

266 }

267 else

268 {

269

270

271

272

273

274

276 }

277 }

278 else

279 {

280

283 }

284

285

286

287

288

289

290

291

292

293

294 if (pipe(pipefd) < 0)

295 elog(FATAL, "pipe() failed: %m");

296 if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) == -1)

297 elog(FATAL, "fcntl(F_SETFL) failed on read-end of self-pipe: %m");

298 if (fcntl(pipefd[1], F_SETFL, O_NONBLOCK) == -1)

299 elog(FATAL, "fcntl(F_SETFL) failed on write-end of self-pipe: %m");

300 if (fcntl(pipefd[0], F_SETFD, FD_CLOEXEC) == -1)

301 elog(FATAL, "fcntl(F_SETFD) failed on read-end of self-pipe: %m");

302 if (fcntl(pipefd[1], F_SETFD, FD_CLOEXEC) == -1)

303 elog(FATAL, "fcntl(F_SETFD) failed on write-end of self-pipe: %m");

304

308

309

312

314#endif

315

316#ifdef WAIT_USE_SIGNALFD

317 sigset_t signalfd_mask;

318

320 {

321

322

323

324

325

326 if (signal_fd != -1)

327 {

328

329 (void) close(signal_fd);

330 signal_fd = -1;

332 }

333 }

334

335

337

338

339 sigemptyset(&signalfd_mask);

340 sigaddset(&signalfd_mask, SIGURG);

341 signal_fd = signalfd(-1, &signalfd_mask, SFD_NONBLOCK | SFD_CLOEXEC);

342 if (signal_fd < 0)

343 elog(FATAL, "signalfd() failed");

345#endif

346

347#ifdef WAIT_USE_KQUEUE

348

350#endif

351}

void ReserveExternalFD(void)

static void latch_sigurg_handler(SIGNAL_ARGS)

static int selfpipe_owner_pid

static int selfpipe_writefd

References Assert(), close, elog, FATAL, IsUnderPostmaster, latch_sigurg_handler(), MyProcPid, pqsignal, ReleaseExternalFD(), ReserveExternalFD(), selfpipe_owner_pid, selfpipe_readfd, selfpipe_writefd, and UnBlockSig.

Referenced by InitPostmasterChild(), InitStandaloneProcess(), and PostmasterMain().

ModifyWaitEvent()

Definition at line 655 of file waiteventset.c.

656{

658#if defined(WAIT_USE_KQUEUE)

659 int old_events;

660#endif

661

662 Assert(pos < set->nevents);

663

664 event = &set->events[pos];

665#if defined(WAIT_USE_KQUEUE)

666 old_events = event->events;

667#endif

668

669

670

671

672

673

674

675

677 {

679 elog(ERROR, "cannot remove postmaster death event");

681 return;

682 }

683

684

685

686

687

688

689

690 if (events == event->events &&

692 return;

693

695 elog(ERROR, "cannot modify latch event");

696

697

698 event->events = events;

699

701 {

703 elog(ERROR, "cannot wait on a latch owned by another process");

704 set->latch = latch;

705

706

707

708

709

710

711

712

713#if defined(WAIT_USE_WIN32)

714 if (!latch)

715 return;

716#else

717 return;

718#endif

719 }

720

721#if defined(WAIT_USE_EPOLL)

722 WaitEventAdjustEpoll(set, event, EPOLL_CTL_MOD);

723#elif defined(WAIT_USE_KQUEUE)

724 WaitEventAdjustKqueue(set, event, old_events);

725#elif defined(WAIT_USE_POLL)

727#elif defined(WAIT_USE_WIN32)

728 WaitEventAdjustWin32(set, event);

729#endif

730}

References Assert(), elog, ERROR, WaitEventSet::events, WaitEvent::events, WaitEventSet::exit_on_postmaster_death, WaitEventSet::latch, MyProcPid, Latch::owner_pid, WaitEventAdjustPoll(), WL_EXIT_ON_PM_DEATH, WL_LATCH_SET, and WL_POSTMASTER_DEATH.

Referenced by pq_check_connection(), secure_read(), secure_write(), SwitchBackToLocalLatch(), SwitchToSharedLatch(), WaitLatch(), and WalSndWait().

WaitEventSetCanReportClosed()

bool WaitEventSetCanReportClosed ( void )

Definition at line 1867 of file waiteventset.c.

1868{

1869#if (defined(WAIT_USE_POLL) && defined(POLLRDHUP)) || \

1870 defined(WAIT_USE_EPOLL) || \

1871 defined(WAIT_USE_KQUEUE)

1872 return true;

1873#else

1874 return false;

1875#endif

1876}

Referenced by check_client_connection_check_interval().

WaitEventSetWait()

Definition at line 1037 of file waiteventset.c.

1040{

1041 int returned_events = 0;

1044 long cur_timeout = -1;

1045

1046 Assert(nevents > 0);

1047

1048

1049

1050

1051

1052 if (timeout >= 0)

1053 {

1055 Assert(timeout >= 0 && timeout <= INT_MAX);

1056 cur_timeout = timeout;

1057 }

1058 else

1060

1062

1063#ifndef WIN32

1065#else

1066

1068#endif

1069 while (returned_events == 0)

1070 {

1071 int rc;

1072

1073

1074

1075

1076

1077

1078

1079

1080

1081

1082

1083

1084

1085

1086

1087

1088

1089

1090

1091

1092

1093

1094

1095

1096

1097

1098

1099

1101 {

1102

1105

1106 }

1107

1109 {

1115 occurred_events++;

1116 returned_events++;

1117

1118

1120

1121 if (returned_events == nevents)

1122 break;

1123

1124

1125

1126

1127

1128

1129 cur_timeout = 0;

1130 timeout = 0;

1131 }

1132

1133

1134

1135

1136

1137

1139 occurred_events, nevents - returned_events);

1140

1141 if (set->latch &&

1144

1145 if (rc == -1)

1146 break;

1147 else

1148 returned_events += rc;

1149

1150

1151 if (returned_events == 0 && timeout >= 0)

1152 {

1156 if (cur_timeout <= 0)

1157 break;

1158 }

1159 }

1160#ifndef WIN32

1162#endif

1163

1165

1166 return returned_events;

1167}

#define pg_memory_barrier()

#define INSTR_TIME_SET_CURRENT(t)

#define INSTR_TIME_SUBTRACT(x, y)

#define INSTR_TIME_GET_MILLISEC(t)

#define INSTR_TIME_SET_ZERO(t)

void pgwin32_dispatch_queued_signals(void)

sig_atomic_t maybe_sleeping

static void pgstat_report_wait_start(uint32 wait_event_info)

static void pgstat_report_wait_end(void)

static int WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, WaitEvent *occurred_events, int nevents)

static volatile sig_atomic_t waiting

References Assert(), WaitEventSet::events, WaitEvent::events, WaitEvent::fd, INSTR_TIME_GET_MILLISEC, INSTR_TIME_SET_CURRENT, INSTR_TIME_SET_ZERO, INSTR_TIME_SUBTRACT, Latch::is_set, WaitEventSet::latch, WaitEventSet::latch_pos, Latch::maybe_sleeping, pg_memory_barrier, PGINVALID_SOCKET, pgstat_report_wait_end(), pgstat_report_wait_start(), pgwin32_dispatch_queued_signals(), WaitEvent::pos, start_time, WaitEvent::user_data, WaitEventSetWaitBlock(), waiting, and WL_LATCH_SET.

Referenced by ExecAppendAsyncEventWait(), pq_check_connection(), secure_read(), secure_write(), ServerLoop(), SysLoggerMain(), WaitLatch(), WaitLatchOrSocket(), and WalSndWait().

WakeupMyProc()

void WakeupMyProc ( void )

WakeupOtherProc()

void WakeupOtherProc ( int pid )