* The checkpointer calls this as needed to update the shared * sync_standbys_defined flag, so that backends don't remain permanently wedged * if synchronous_standby_names is unset. It's safe to check the current value * without the lock, because it's only ever updated by one process. But we * must take the lock to change it. */
| 1174 | * must take the lock to change it. |
| 1175 | */ |
| 1176 | void |
| 1177 | SyncRepUpdateSyncStandbysDefined(void) |
| 1178 | { |
| 1179 | bool sync_standbys_defined = SyncStandbysDefined(); |
| 1180 | |
| 1181 | if (sync_standbys_defined != WalSndCtl->sync_standbys_defined) |
| 1182 | { |
| 1183 | LWLockAcquire(SyncRepLock, LW_EXCLUSIVE); |
| 1184 | |
| 1185 | /* |
| 1186 | * If synchronous_standby_names has been reset to empty, it's futile |
| 1187 | * for backends to continue waiting. Since the user no longer wants |
| 1188 | * synchronous replication, we'd better wake them up. |
| 1189 | */ |
| 1190 | if (!sync_standbys_defined) |
| 1191 | { |
| 1192 | int i; |
| 1193 | |
| 1194 | for (i = 0; i < NUM_SYNC_REP_WAIT_MODE; i++) |
| 1195 | SyncRepWakeQueue(true, i); |
| 1196 | } |
| 1197 | |
| 1198 | /* |
| 1199 | * Only allow people to join the queue when there are synchronous |
| 1200 | * standbys defined. Without this interlock, there's a race |
| 1201 | * condition: we might wake up all the current waiters; then, some |
| 1202 | * backend that hasn't yet reloaded its config might go to sleep on |
| 1203 | * the queue (and never wake up). This prevents that. |
| 1204 | */ |
| 1205 | WalSndCtl->sync_standbys_defined = sync_standbys_defined; |
| 1206 | |
| 1207 | LWLockRelease(SyncRepLock); |
| 1208 | } |
| 1209 | } |
| 1210 | |
| 1211 | #ifdef USE_ASSERT_CHECKING |
| 1212 | static bool |
no test coverage detected