* ParallelSlotsGetIdle * Return a connection slot that is ready to execute a command. * * The slot returned is chosen as follows: * * If any idle slot already has an open connection, and if either dbname is * null or the existing connection is to the given database, that slot will be * returned allowing the connection to be reused. * * Otherwise, if any idle slot is not yet connected to
| 340 | * If an error occurs, NULL is returned. |
| 341 | */ |
| 342 | ParallelSlot * |
| 343 | ParallelSlotsGetIdle(ParallelSlotArray *sa, const char *dbname) |
| 344 | { |
| 345 | int offset; |
| 346 | |
| 347 | Assert(sa); |
| 348 | Assert(sa->numslots > 0); |
| 349 | |
| 350 | while (1) |
| 351 | { |
| 352 | /* First choice: a slot already connected to the desired database. */ |
| 353 | offset = find_matching_idle_slot(sa, dbname); |
| 354 | if (offset >= 0) |
| 355 | { |
| 356 | sa->slots[offset].inUse = true; |
| 357 | return &sa->slots[offset]; |
| 358 | } |
| 359 | |
| 360 | /* Second choice: a slot not connected to any database. */ |
| 361 | offset = find_unconnected_slot(sa); |
| 362 | if (offset >= 0) |
| 363 | { |
| 364 | connect_slot(sa, offset, dbname); |
| 365 | sa->slots[offset].inUse = true; |
| 366 | return &sa->slots[offset]; |
| 367 | } |
| 368 | |
| 369 | /* Third choice: a slot connected to the wrong database. */ |
| 370 | offset = find_any_idle_slot(sa); |
| 371 | if (offset >= 0) |
| 372 | { |
| 373 | disconnectDatabase(sa->slots[offset].connection); |
| 374 | sa->slots[offset].connection = NULL; |
| 375 | connect_slot(sa, offset, dbname); |
| 376 | sa->slots[offset].inUse = true; |
| 377 | return &sa->slots[offset]; |
| 378 | } |
| 379 | |
| 380 | /* |
| 381 | * Fourth choice: block until one or more slots become available. If |
| 382 | * any slots hit a fatal error, we'll find out about that here and |
| 383 | * return NULL. |
| 384 | */ |
| 385 | if (!wait_on_slots(sa)) |
| 386 | return NULL; |
| 387 | } |
| 388 | } |
| 389 | |
| 390 | /* |
| 391 | * ParallelSlotsSetup |
no test coverage detected