| 269 | } |
| 270 | |
| 271 | void connSocketEventHandler(struct aeEventLoop *el, int fd, void *clientData, int mask) |
| 272 | { |
| 273 | UNUSED(el); |
| 274 | UNUSED(fd); |
| 275 | connection *conn = (connection*)clientData; |
| 276 | |
| 277 | if (conn->state.load(std::memory_order_relaxed) == CONN_STATE_CONNECTING && |
| 278 | (mask & AE_WRITABLE) && conn->conn_handler) { |
| 279 | |
| 280 | int conn_error = connGetSocketError(conn); |
| 281 | if (conn_error) { |
| 282 | conn->last_errno = conn_error; |
| 283 | conn->state.store(CONN_STATE_ERROR, std::memory_order_release); |
| 284 | } else { |
| 285 | conn->state.store(CONN_STATE_CONNECTED, std::memory_order_release); |
| 286 | } |
| 287 | |
| 288 | if (!conn->write_handler) aeDeleteFileEvent(serverTL->el,conn->fd,AE_WRITABLE); |
| 289 | |
| 290 | { |
| 291 | AeLocker locker; |
| 292 | locker.arm(nullptr); |
| 293 | if (!callHandler(conn, conn->conn_handler)) return; |
| 294 | } |
| 295 | conn->conn_handler = NULL; |
| 296 | } |
| 297 | |
| 298 | /* Normally we execute the readable event first, and the writable |
| 299 | * event later. This is useful as sometimes we may be able |
| 300 | * to serve the reply of a query immediately after processing the |
| 301 | * query. |
| 302 | * |
| 303 | * However if WRITE_BARRIER is set in the mask, our application is |
| 304 | * asking us to do the reverse: never fire the writable event |
| 305 | * after the readable. In such a case, we invert the calls. |
| 306 | * This is useful when, for instance, we want to do things |
| 307 | * in the beforeSleep() hook, like fsync'ing a file to disk, |
| 308 | * before replying to a client. */ |
| 309 | int invert = conn->flags & CONN_FLAG_WRITE_BARRIER; |
| 310 | |
| 311 | int call_write = (mask & AE_WRITABLE) && conn->write_handler; |
| 312 | int call_read = (mask & AE_READABLE) && conn->read_handler; |
| 313 | |
| 314 | /* Handle normal I/O flows */ |
| 315 | if (!invert && call_read) { |
| 316 | AeLocker lock; |
| 317 | if (!(conn->flags & CONN_FLAG_READ_THREADSAFE)) |
| 318 | lock.arm(nullptr); |
| 319 | |
| 320 | if (!callHandler(conn, conn->read_handler)) return; |
| 321 | } |
| 322 | /* Fire the writable event. */ |
| 323 | if (call_write) { |
| 324 | AeLocker lock; |
| 325 | if (!(conn->flags & CONN_FLAG_WRITE_THREADSAFE)) |
| 326 | lock.arm(nullptr); |
| 327 | |
| 328 | if (!callHandler(conn, conn->write_handler)) return; |
nothing calls this directly
no test coverage detected