Schedule a client to free it at a safe time in the serverCron() function. * This function is useful when we need to terminate a client but we are in * a context where calling freeClient() is not possible, because the client * should be valid for the continuation of the flow of the program. */
| 1446 | * a context where calling freeClient() is not possible, because the client |
| 1447 | * should be valid for the continuation of the flow of the program. */ |
| 1448 | void freeClientAsync(client *c) { |
| 1449 | /* We need to handle concurrent access to the server.clients_to_close list |
| 1450 | * only in the freeClientAsync() function, since it's the only function that |
| 1451 | * may access the list while Redis uses I/O threads. All the other accesses |
| 1452 | * are in the context of the main thread while the other threads are |
| 1453 | * idle. */ |
| 1454 | if (c->flags & CLIENT_CLOSE_ASAP || c->flags & CLIENT_LUA) return; |
| 1455 | c->flags |= CLIENT_CLOSE_ASAP; |
| 1456 | if (server.io_threads_num == 1) { |
| 1457 | /* no need to bother with locking if there's just one thread (the main thread) */ |
| 1458 | listAddNodeTail(server.clients_to_close,c); |
| 1459 | return; |
| 1460 | } |
| 1461 | static pthread_mutex_t async_free_queue_mutex = PTHREAD_MUTEX_INITIALIZER; |
| 1462 | pthread_mutex_lock(&async_free_queue_mutex); |
| 1463 | listAddNodeTail(server.clients_to_close,c); |
| 1464 | pthread_mutex_unlock(&async_free_queue_mutex); |
| 1465 | } |
| 1466 | |
| 1467 | /* Free the clients marked as CLOSE_ASAP, return the number of clients |
| 1468 | * freed. */ |
no test coverage detected