void redisAsyncHandleWrite(redisAsyncContext *ac) { redisContext *c = &(ac->c); int done = 0; int ret = 0; if (!(c->flags & REDIS_CONNECTED)) { /* Abort connect was not successful. */ if (__redisAsyncHandleConnect(ac) != REDIS_OK) return; /* Try again later when the context is still not connected. */ if (!(c->flags & REDIS_CONNECTED)) return; } LOCK(obuf_mtx); ret = redisBufferWrite(c,&done); UNLOCK(obuf_mtx); if (ret == REDIS_ERR) { __redisAsyncDisconnect(ac); } else { /* Continue writing when not done, stop writing otherwise */ if (!done) _EL_ADD_WRITE(ac); else _EL_DEL_WRITE(ac); /* Always schedule reads after writes */ _EL_ADD_READ(ac); } }
/* This function should be called when the socket is readable. * It processes all replies that can be read and executes their callbacks. */ void redisAsyncHandleRead(redisAsyncContext *ac) { redisContext *c = &(ac->c); if (!(c->flags & REDIS_CONNECTED)) { /* Abort connect was not successful. */ if (__redisAsyncHandleConnect(ac) != REDIS_OK) return; /* Try again later when the context is still not connected. */ if (!(c->flags & REDIS_CONNECTED)) return; } if (redisBufferRead(c) == REDIS_ERR) { __redisAsyncDisconnect(ac); } else { /* Always re-schedule reads */ #ifdef _WIN32 // There appears to be a bug in the Linux version of _EL_ADD_READ which will not reschedule // the read if already reading. This is a problem if there is a large number of async GET // operations. If the receive buffer is exhausted with the data returned, the read would // not be rescheduled, and the async operations would cease. This forces the read to recur. _EL_FORCE_ADD_READ(ac); #else _EL_ADD_READ(ac); #endif redisProcessCallbacks(ac); } }
/* The redisAsyncHandleWrite is split into a Prep and Complete routines To allow using a write routine suitable for async behavior. For Windows this will use IOCP on write. */ int redisAsyncHandleWritePrep(redisAsyncContext *ac) { redisContext *c = &(ac->c); if (!(c->flags & REDIS_CONNECTED)) { /* Abort connect was not successful. */ if (__redisAsyncHandleConnect(ac) != REDIS_OK) return REDIS_ERR; /* Try again later when the context is still not connected. */ if (!(c->flags & REDIS_CONNECTED)) return REDIS_ERR; } return REDIS_OK; }
/* This function should be called when the socket is readable. * It processes all replies that can be read and executes their callbacks. */ void redisAsyncHandleRead(redisAsyncContext *ac) { redisContext *c = &(ac->c); if (!(c->flags & REDIS_CONNECTED)) { /* Abort connect was not successful. */ if (__redisAsyncHandleConnect(ac) != REDIS_OK) return; /* Try again later when the context is still not connected. */ if (!(c->flags & REDIS_CONNECTED)) return; } if (redisBufferRead(c) == REDIS_ERR) { __redisAsyncDisconnect(ac); } else { /* Always re-schedule reads */ _EL_ADD_READ(ac); redisProcessCallbacks(ac); } }