@@ -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