Unify DCB close processing to single function dcb_close. Remove dcb_add_to_zombieslist (incorporating logic into dcb_close). Alter logic so that DCB that is just allocated will still go to zombie list if dcb->fd is not closed.
This commit is contained in:
		| @ -248,50 +248,6 @@ dcb_free(DCB *dcb) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /**  | ||||
|  * Add the DCB to the end of zombies list.  | ||||
|  * | ||||
|  * Adding to list occurs once per DCB. This is ensured by changing the | ||||
|  * state of DCB to DCB_STATE_ZOMBIE after addition. Prior insertion, DCB state | ||||
|  * is checked and operation proceeds only if state differs from DCB_STATE_ZOMBIE. | ||||
|  * @param dcb The DCB to add to the zombie list | ||||
|  * @return none | ||||
|  */ | ||||
| void | ||||
| dcb_add_to_zombieslist(DCB *dcb) | ||||
| { | ||||
|         bool        succp = false; | ||||
|         dcb_state_t prev_state = DCB_STATE_UNDEFINED; | ||||
|          | ||||
|         CHK_DCB(dcb);         | ||||
|  | ||||
|         /*< | ||||
|          * Protect zombies list access. | ||||
|          */ | ||||
| 	spinlock_acquire(&zombiespin); | ||||
|         /*< | ||||
|          * If dcb is already added to zombies list, return. | ||||
|          */ | ||||
|         if (dcb->state != DCB_STATE_NOPOLLING) { | ||||
|                 ss_dassert(dcb->state != DCB_STATE_POLLING && | ||||
|                            dcb->state != DCB_STATE_LISTENING); | ||||
|                 spinlock_release(&zombiespin); | ||||
|                 return; | ||||
|         } | ||||
|         /*< | ||||
|          * Add closing dcb to the top of the list. | ||||
|          */ | ||||
|         dcb->memdata.next = zombies; | ||||
|         zombies = dcb; | ||||
|         /*< | ||||
|          * Set state which indicates that it has been added to zombies | ||||
|          * list. | ||||
|          */ | ||||
|         dcb->state = DCB_STATE_ZOMBIE; | ||||
|          | ||||
| 	spinlock_release(&zombiespin); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Clone a DCB for internal use, mostly used for specialist filters | ||||
|  * to create dummy clients based on real clients. | ||||
| @ -600,7 +556,6 @@ bool    succp = false; | ||||
| 			&tls_log_info.li_enabled_logs))); | ||||
|  | ||||
|                 dcb->state = DCB_STATE_DISCONNECTED; | ||||
|                 ss_dassert(succp); | ||||
| 		dcb_next = dcb->memdata.next; | ||||
|                 dcb_final_free(dcb); | ||||
|                 dcb = dcb_next; | ||||
| @ -1928,72 +1883,91 @@ dcb_drain_writeq_SSL(DCB *dcb) | ||||
| void | ||||
| dcb_close(DCB *dcb) | ||||
| { | ||||
|         int  rc = 0; | ||||
|     int  rc = 0; | ||||
|  | ||||
|         CHK_DCB(dcb); | ||||
|     CHK_DCB(dcb); | ||||
|  | ||||
| 	LOGIF(LD, (skygw_log_write(LOGFILE_DEBUG, | ||||
| 				"%lu [dcb_close]", | ||||
| 				pthread_self())));                                 | ||||
| 	 | ||||
|         /** | ||||
|          * dcb_close may be called for freshly created dcb, in which case | ||||
|          * it only needs to be freed. | ||||
|          */ | ||||
|         if (dcb->state == DCB_STATE_ALLOC) | ||||
|     LOGIF(LD, (skygw_log_write(LOGFILE_DEBUG, | ||||
|         "%lu [dcb_close]", | ||||
|         pthread_self())));                                 | ||||
|  | ||||
|     if (DCB_STATE_UNDEFINED == dcb->state | ||||
|         || DCB_STATE_DISCONNECTED == dcb->state | ||||
|         || DCB_STATE_ZOMBIE == dcb->state) | ||||
|     { | ||||
|         LOGIF(LE, (skygw_log_write( | ||||
|             LOGFILE_ERROR, | ||||
|             "%lu [dcb_close] Error : Removing DCB %p but was in state %s " | ||||
|             "which is not legal for a call to dcb_close. ", | ||||
|             pthread_self(), | ||||
|             dcb, | ||||
|             STRDCBSTATE(dcb->state)))); | ||||
|         assert(false); | ||||
|     } | ||||
|      | ||||
|     /** | ||||
|      * dcb_close may be called for freshly created dcb, in which case | ||||
|      * it only needs to be freed. | ||||
|      */ | ||||
|     if (dcb->state == DCB_STATE_ALLOC && dcb->fd != DCBFD_CLOSED) | ||||
|     { | ||||
|         dcb_final_free(dcb); | ||||
|         return; | ||||
|     } | ||||
|          | ||||
|     /*< | ||||
|      * Stop dcb's listening and modify state accordingly. | ||||
|      */ | ||||
|     if (dcb->state == DCB_STATE_POLLING  || dcb->state == DCB_STATE_LISTENING) | ||||
|     { | ||||
|         if (dcb->state == DCB_STATE_LISTENING) | ||||
|         { | ||||
|                 dcb_final_free(dcb); | ||||
|                 return; | ||||
|             LOGIF(LE, (skygw_log_write( | ||||
|                 LOGFILE_ERROR, | ||||
|                 "%lu [dcb_close] Error : Removing DCB %p but was in state %s " | ||||
|                 "which is not expected for a call to dcb_close, although it" | ||||
|                 "should be processed correctly. ", | ||||
|                 pthread_self(), | ||||
|                 dcb, | ||||
|                 STRDCBSTATE(dcb->state)))); | ||||
|         } | ||||
|         rc = poll_remove_dcb(dcb); | ||||
|         /* | ||||
|          * Return will always be 0 or function will have crashed | ||||
|          */ | ||||
|         LOGIF(LD, (skygw_log_write( | ||||
|             LOGFILE_DEBUG, | ||||
|             "%lu [dcb_close] Removed dcb %p in state %s from " | ||||
|             "poll set.", | ||||
|             pthread_self(), | ||||
|             dcb, | ||||
|             STRDCBSTATE(dcb->state)))); | ||||
|         /** | ||||
|          * close protocol and router session | ||||
|          */ | ||||
|         if (dcb->func.close != NULL) | ||||
|         { | ||||
|             dcb->func.close(dcb); | ||||
|         } | ||||
|         /** Call possible callback for this DCB in case of close */ | ||||
|         dcb_call_callback(dcb, DCB_REASON_CLOSE); | ||||
|     } | ||||
|     assert (dcb->state == DCB_STATE_NOPOLLING  || dcb->state == DCB_STATE_ALLOC); | ||||
|      | ||||
|     spinlock_acquire(&zombiespin); | ||||
|      | ||||
|     /*< | ||||
|      * Add closing dcb to the top of the list. | ||||
|      */ | ||||
|     dcb->memdata.next = zombies; | ||||
|     zombies = dcb; | ||||
|     /*< | ||||
|      * Set state which indicates that it has been added to zombies | ||||
|      * list. | ||||
|      */ | ||||
|     dcb->state = DCB_STATE_ZOMBIE; | ||||
|          | ||||
|         ss_dassert(dcb->state == DCB_STATE_POLLING || | ||||
|                dcb->state == DCB_STATE_NOPOLLING || | ||||
|                dcb->state == DCB_STATE_ZOMBIE); | ||||
|          | ||||
|         /*< | ||||
|         * Stop dcb's listening and modify state accordingly. | ||||
|         */ | ||||
| 	if (dcb->state == DCB_STATE_POLLING) | ||||
| 	{ | ||||
| 		rc = poll_remove_dcb(dcb); | ||||
|  | ||||
| 		if (rc == 0) { | ||||
| 			LOGIF(LD, (skygw_log_write( | ||||
| 				LOGFILE_DEBUG, | ||||
| 				"%lu [dcb_close] Removed dcb %p in state %s from " | ||||
| 				"poll set.", | ||||
| 				pthread_self(), | ||||
| 				dcb, | ||||
| 				STRDCBSTATE(dcb->state)))); | ||||
| 		} else { | ||||
| 			LOGIF(LE, (skygw_log_write( | ||||
| 				LOGFILE_ERROR, | ||||
| 				"Error : Removing DCB fd == %d in state %s from " | ||||
| 				"poll set failed.", | ||||
| 				dcb->fd, | ||||
| 				STRDCBSTATE(dcb->state)))); | ||||
| 		} | ||||
| 	 | ||||
| 		if (rc == 0) | ||||
| 		{ | ||||
| 			/** | ||||
| 			 * close protocol and router session | ||||
| 			 */ | ||||
| 			if (dcb->func.close != NULL) | ||||
| 			{ | ||||
| 				dcb->func.close(dcb); | ||||
| 			} | ||||
| 			/** Call possible callback for this DCB in case of close */ | ||||
| 			dcb_call_callback(dcb, DCB_REASON_CLOSE); | ||||
| 			 | ||||
| 			if (dcb->state == DCB_STATE_NOPOLLING)  | ||||
| 			{ | ||||
| 				dcb_add_to_zombieslist(dcb); | ||||
| 			} | ||||
| 		} | ||||
| 	        ss_dassert(dcb->state == DCB_STATE_NOPOLLING || | ||||
| 					dcb->state == DCB_STATE_ZOMBIE);	 | ||||
| 	} | ||||
|     spinlock_release(&zombiespin); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  | ||||
| @ -302,10 +302,6 @@ poll_add_dcb(DCB *dcb) | ||||
|                 dcb, | ||||
|                 STRDCBSTATE(dcb->state)))); | ||||
|         } | ||||
|         /*< | ||||
|          * If dcb is in unexpected state, state change fails indicating that dcb | ||||
|          * is not polling anymore. | ||||
|          */ | ||||
|         dcb->state = new_state;  | ||||
|         spinlock_release(&dcb->dcb_initlock); | ||||
|         /* | ||||
|  | ||||
| @ -64,7 +64,7 @@ int     buflen; | ||||
|         ss_info_dassert(!dcb_isvalid(dcb), "Freed DCB must not be valid"); | ||||
|         ss_dfprintf(stderr, "\t..done\nMake clone DCB a zombie"); | ||||
|         clone->state = DCB_STATE_NOPOLLING; | ||||
|         dcb_add_to_zombieslist(clone); | ||||
|         dcb_close(clone); | ||||
|         ss_info_dassert(dcb_get_zombies() == clone, "Clone DCB must be start of zombie list now"); | ||||
|         ss_dfprintf(stderr, "\t..done\nProcess the zombies list"); | ||||
|         dcb_process_zombies(0); | ||||
|  | ||||
| @ -330,7 +330,6 @@ const char 	*gw_dcb_state2string(int);		/* DCB state to string */ | ||||
| void		dcb_printf(DCB *, const char *, ...);	/* DCB version of printf */ | ||||
| int		dcb_isclient(DCB *);			/* the DCB is the client of the session */ | ||||
| void		dcb_hashtable_stats(DCB *, void *);	/**< Print statisitics */ | ||||
| void            dcb_add_to_zombieslist(DCB* dcb); | ||||
| int		dcb_add_callback(DCB *, DCB_REASON, int	(*)(struct dcb *, DCB_REASON, void *), | ||||
| 			 void *); | ||||
| int		dcb_remove_callback(DCB *, DCB_REASON, int (*)(struct dcb *, DCB_REASON, void *), | ||||
|  | ||||
| @ -270,9 +270,7 @@ int	n_connect = 0; | ||||
| 		{ | ||||
| 			atomic_add(&dcb->stats.n_accepts, 1); | ||||
|                         client_dcb = dcb_alloc(DCB_ROLE_REQUEST_HANDLER); | ||||
|  | ||||
| 			if (client_dcb == NULL) | ||||
|  | ||||
| 			{ | ||||
| 				close(so); | ||||
| 				return n_connect; | ||||
| @ -283,7 +281,8 @@ int	n_connect = 0; | ||||
|                         if ((maxscaled_pr = (MAXSCALED *)malloc(sizeof(MAXSCALED))) == NULL) | ||||
| 			{ | ||||
|                         	client_dcb->protocol = NULL; | ||||
|                                 dcb_add_to_zombieslist(client_dcb); | ||||
|                                 close(so); | ||||
|                                 dcb_close(client_dcb); | ||||
| 				return n_connect; | ||||
| 			} | ||||
| 			maxscaled_pr->username = NULL; | ||||
| @ -293,9 +292,9 @@ int	n_connect = 0; | ||||
| 			client_dcb->session = | ||||
|                                 session_alloc(dcb->session->service, client_dcb); | ||||
|  | ||||
| 			if (poll_add_dcb(client_dcb) == -1) | ||||
| 			if (poll_add_dcb(client_dcb)) | ||||
| 			{ | ||||
|                                 dcb_add_to_zombieslist(dcb); | ||||
|                                 dcb_close(dcb); | ||||
| 				return n_connect; | ||||
| 			} | ||||
| 			n_connect++; | ||||
|  | ||||
| @ -315,13 +315,13 @@ int	n_connect = 0; | ||||
|  | ||||
|                         if (telnetd_pr == NULL) | ||||
|                         { | ||||
|                                 dcb_add_to_zombieslist(client_dcb); | ||||
|                                 dcb_close(client_dcb); | ||||
| 				return n_connect; | ||||
| 			} | ||||
|  | ||||
| 			if (poll_add_dcb(client_dcb) == -1) | ||||
| 			if (poll_add_dcb(client_dcb)) | ||||
| 			{ | ||||
|                                 dcb_add_to_zombieslist(dcb); | ||||
|                                 dcb_close(dcb); | ||||
| 				return n_connect; | ||||
| 			} | ||||
| 			n_connect++; | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 counterpoint
					counterpoint