@@ -133,20 +133,16 @@ redis_error_throw(RedisSock *redis_sock TSRMLS_DC)
133133 }
134134}
135135
136- PHP_REDIS_API void redis_stream_close (RedisSock * redis_sock TSRMLS_DC ) {
137- if (!redis_sock -> persistent ) {
138- php_stream_close (redis_sock -> stream );
139- } else {
140- php_stream_pclose (redis_sock -> stream );
141- }
142- }
143-
144136PHP_REDIS_API int
145137redis_check_eof (RedisSock * redis_sock , int no_throw TSRMLS_DC )
146138{
147139 int count ;
140+ char * errmsg ;
148141
149- if (!redis_sock -> stream ) {
142+ if (!redis_sock || !redis_sock -> stream || redis_sock -> status == REDIS_SOCK_STATUS_FAILED ) {
143+ if (!no_throw ) {
144+ zend_throw_exception (redis_exception_ce , "Connection closed" , 0 TSRMLS_CC );
145+ }
150146 return -1 ;
151147 }
152148
@@ -169,51 +165,47 @@ redis_check_eof(RedisSock *redis_sock, int no_throw TSRMLS_DC)
169165 /* Success */
170166 return 0 ;
171167 } else if (redis_sock -> mode == MULTI || redis_sock -> watching ) {
172- REDIS_STREAM_CLOSE_MARK_FAILED (redis_sock );
173- if (!no_throw ) {
174- zend_throw_exception (redis_exception_ce ,
175- "Connection lost and socket is in MULTI/watching mode" ,
176- 0 TSRMLS_CC );
177- }
178- return -1 ;
179- }
180- /* TODO: configurable max retry count */
181- for (count = 0 ; count < 10 ; ++ count ) {
182- /* close existing stream before reconnecting */
183- if (redis_sock -> stream ) {
184- redis_stream_close (redis_sock TSRMLS_CC );
185- redis_sock -> stream = NULL ;
186- }
187- // Wait for a while before trying to reconnect
188- if (redis_sock -> retry_interval ) {
189- // Random factor to avoid having several (or many) concurrent connections trying to reconnect at the same time
190- long retry_interval = (count ? redis_sock -> retry_interval : (php_rand (TSRMLS_C ) % redis_sock -> retry_interval ));
191- usleep (retry_interval );
192- }
193- /* reconnect */
194- if (redis_sock_connect (redis_sock TSRMLS_CC ) == 0 ) {
195- /* check for EOF again. */
196- errno = 0 ;
197- if (php_stream_eof (redis_sock -> stream ) == 0 ) {
198- /* If we're using a password, attempt a reauthorization */
199- if (redis_sock -> auth && resend_auth (redis_sock TSRMLS_CC ) != 0 ) {
200- break ;
201- }
202- /* If we're using a non-zero db, reselect it */
203- if (redis_sock -> dbNumber && reselect_db (redis_sock TSRMLS_CC ) != 0 ) {
204- break ;
168+ errmsg = "Connection lost and socket is in MULTI/watching mode" ;
169+ } else {
170+ errmsg = "Connection lost" ;
171+ /* TODO: configurable max retry count */
172+ for (count = 0 ; count < 10 ; ++ count ) {
173+ /* close existing stream before reconnecting */
174+ if (redis_sock -> stream ) {
175+ redis_sock_disconnect (redis_sock , 1 TSRMLS_CC );
176+ }
177+ // Wait for a while before trying to reconnect
178+ if (redis_sock -> retry_interval ) {
179+ // Random factor to avoid having several (or many) concurrent connections trying to reconnect at the same time
180+ long retry_interval = (count ? redis_sock -> retry_interval : (php_rand (TSRMLS_C ) % redis_sock -> retry_interval ));
181+ usleep (retry_interval );
182+ }
183+ /* reconnect */
184+ if (redis_sock_connect (redis_sock TSRMLS_CC ) == 0 ) {
185+ /* check for EOF again. */
186+ errno = 0 ;
187+ if (php_stream_eof (redis_sock -> stream ) == 0 ) {
188+ /* If we're using a password, attempt a reauthorization */
189+ if (redis_sock -> auth && resend_auth (redis_sock TSRMLS_CC ) != 0 ) {
190+ errmsg = "AUTH failed while reconnecting" ;
191+ break ;
192+ }
193+ /* If we're using a non-zero db, reselect it */
194+ if (redis_sock -> dbNumber && reselect_db (redis_sock TSRMLS_CC ) != 0 ) {
195+ errmsg = "SELECT failed while reconnecting" ;
196+ break ;
197+ }
198+ /* Success */
199+ return 0 ;
205200 }
206- /* Success */
207- return 0 ;
208201 }
209202 }
210203 }
211- /* close stream if still here */
212- if (redis_sock -> stream ) {
213- REDIS_STREAM_CLOSE_MARK_FAILED (redis_sock );
214- }
204+ /* close stream and mark socket as failed */
205+ redis_sock_disconnect (redis_sock , 1 TSRMLS_CC );
206+ redis_sock -> status = REDIS_SOCK_STATUS_FAILED ;
215207 if (!no_throw ) {
216- zend_throw_exception (redis_exception_ce , "Connection lost" , 0 TSRMLS_CC );
208+ zend_throw_exception (redis_exception_ce , errmsg , 0 TSRMLS_CC );
217209 }
218210 return -1 ;
219211}
@@ -1427,7 +1419,7 @@ PHP_REDIS_API int redis_sock_connect(RedisSock *redis_sock TSRMLS_DC)
14271419#endif
14281420
14291421 if (redis_sock -> stream != NULL ) {
1430- redis_sock_disconnect (redis_sock TSRMLS_CC );
1422+ redis_sock_disconnect (redis_sock , 0 TSRMLS_CC );
14311423 }
14321424
14331425 tv .tv_sec = (time_t )redis_sock -> timeout ;
@@ -1532,28 +1524,26 @@ redis_sock_server_open(RedisSock *redis_sock TSRMLS_DC)
15321524/**
15331525 * redis_sock_disconnect
15341526 */
1535- PHP_REDIS_API int redis_sock_disconnect (RedisSock * redis_sock TSRMLS_DC )
1527+ PHP_REDIS_API int
1528+ redis_sock_disconnect (RedisSock * redis_sock , int force TSRMLS_DC )
15361529{
15371530 if (redis_sock == NULL ) {
1538- return 1 ;
1539- }
1540-
1541- redis_sock -> dbNumber = 0 ;
1542- if (redis_sock -> stream != NULL ) {
1543- redis_sock -> status = REDIS_SOCK_STATUS_DISCONNECTED ;
1544- redis_sock -> watching = 0 ;
1545-
1546- /* Stil valid? */
1547- if (!redis_sock -> persistent ) {
1531+ return FAILURE ;
1532+ } else if (redis_sock -> stream ) {
1533+ if (redis_sock -> persistent ) {
1534+ if (force ) {
1535+ php_stream_pclose (redis_sock -> stream );
1536+ }
1537+ } else {
15481538 php_stream_close (redis_sock -> stream );
15491539 }
1550-
15511540 redis_sock -> stream = NULL ;
1552-
1553- return 1 ;
15541541 }
1542+ redis_sock -> mode = ATOMIC ;
1543+ redis_sock -> status = REDIS_SOCK_STATUS_DISCONNECTED ;
1544+ redis_sock -> watching = 0 ;
15551545
1556- return 0 ;
1546+ return SUCCESS ;
15571547}
15581548
15591549/**
@@ -1764,11 +1754,8 @@ PHP_REDIS_API int redis_mbulk_reply_assoc(INTERNAL_FUNCTION_PARAMETERS, RedisSoc
17641754PHP_REDIS_API int
17651755redis_sock_write (RedisSock * redis_sock , char * cmd , size_t sz TSRMLS_DC )
17661756{
1767- if (!redis_sock || redis_sock -> status == REDIS_SOCK_STATUS_DISCONNECTED ) {
1768- zend_throw_exception (redis_exception_ce , "Connection closed" ,
1769- 0 TSRMLS_CC );
1770- } else if (redis_check_eof (redis_sock , 0 TSRMLS_CC ) == 0 &&
1771- php_stream_write (redis_sock -> stream , cmd , sz ) == sz
1757+ if (redis_check_eof (redis_sock , 0 TSRMLS_CC ) == 0 &&
1758+ php_stream_write (redis_sock -> stream , cmd , sz ) == sz
17721759 ) {
17731760 return sz ;
17741761 }
@@ -2044,8 +2031,8 @@ redis_sock_gets(RedisSock *redis_sock, char *buf, int buf_size,
20442031 if (php_stream_get_line (redis_sock -> stream , buf , buf_size , line_size )
20452032 == NULL )
20462033 {
2047- // Close, put our socket state into error
2048- REDIS_STREAM_CLOSE_MARK_FAILED (redis_sock );
2034+ // Close our socket
2035+ redis_sock_disconnect (redis_sock , 1 TSRMLS_CC );
20492036
20502037 // Throw a read error exception
20512038 zend_throw_exception (redis_exception_ce , "read error on connection" ,
0 commit comments