Esempio n. 1
0
int conn_close_with_my(conn_t *c)
{//这个操作很重,会干掉mysql的连接,已经客户端连接等所有数据!!!!
    int res = 0;

    list_del_init(&(c->link));

    if(c->my){
        if( (res = my_conn_close(c->my)) < 0 ){
            log(g_log, "my conn close error\n");
        }
        c->my = NULL;
    }

    if( (res = cli_conn_close(c->cli)) < 0 ){
        log(g_log, "cli conn close error\n");
    }
    c->cli = NULL;

    if( (res = conn_release(c)) < 0 ){
        log(g_log, "conn release error\n");
    }

    debug(g_log, "conn:%u connection close\n", c->connid);

    return res;
}
Esempio n. 2
0
int conn_close(conn_t *c)
{
    int res = 0;

    list_del_init(&(c->link));

    if(c->my){
        if( (res = my_conn_put(c->my, 1)) < 0 ){
            log(g_log, "put my conn error\n");
        }
        c->my = NULL;
    }

    if( (res = cli_conn_close(c->cli)) < 0 ){
        log(g_log, "cli conn close error\n");
    }
    c->cli = NULL;

    if( (res = conn_release(c)) < 0 ){
        log(g_log, "conn release error\n");
    }

    debug(g_log, "conn:%u connection close\n", c->connid);

    return res;
}
Esempio n. 3
0
void closeclient(int epfd, int fd)
{
    close(fd);
    conn_release(fd);
    // kernel 2.6.9 +, event can be set to NULL
    epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL);
}
Esempio n. 4
0
conn_t *conn_open(int fd, uint32_t ip, uint16_t port)
{//分配conn_t和cli_conn_t, 并挂接起来 
    int res = 0;
    conn_t *c;

    if( (c = conn_alloc()) == NULL ){//这个连接其实是个中间搭桥的连接。
        log(g_log, "conn alloc error\n");
        return NULL;
    }

    if( (res = cli_conn_open(c, fd, ip, port)) < 0 ){//将c跟当前的fd连接起来,建立一个客户端连接结构
        log(g_log, "cli conn open error\n");
        conn_release(c);
        return NULL;
    }

    return c;
}
Esempio n. 5
0
struct task_act *
task_select (int *secs_p)
{
	struct connection	* cn;
	struct connection	* cn_tmp;
	struct connection	**next_cn;
	struct task_act	* tk;
	struct task_act	**next_tk;
	struct oper_act	* on;
	int			  timeout_tmp;
	char		  process_edbs = TRUE;
	char		  do_timeout;
	int			  suspended = FALSE;
	int 		  xi = 0;
	struct task_act	* ret_tk = NULLTASK;
	extern char	  startup_update;
	struct oper_act	* newop = NULLOPER;

	 time (&timenow);
	(*secs_p) = NOTOK;
	conns_used = 0;

	/*
	    DLOG(log_dsap, LLOG_DEBUG, ("task_select connections:"));
	    conn_list_log(connlist);
	*/

	for(cn=connlist; cn!=NULLCONN; cn=cn_tmp) {
		cn_tmp = cn->cn_next;	/* Nasty but necessary in conn_extract()
				   manages to get itself called somehow */

		do_timeout = FALSE;

#ifdef DEBUG
		conn_log(cn,LLOG_DEBUG);
#endif

		next_tk = &(cn->cn_tasklist);
		for(tk=cn->cn_tasklist; tk!=NULLTASK; tk=(*next_tk)) {
			if(tk->tk_timed) {
				if(tk->tk_timeout <= timenow) {
#ifdef DEBUG
					struct UTCtime	  ut;
					struct UTCtime	  ut2;

					DLOG(log_dsap, LLOG_TRACE, ("task has timelimit of %ld", tk->tk_timeout));
					tm2ut(gmtime(&(tk->tk_timeout)), &ut);
					DLOG(log_dsap, LLOG_DEBUG, ("converted timelimit = %s", utct2str(&(ut))));
					tm2ut(gmtime(&(timenow)), &ut2);
					DLOG(log_dsap, LLOG_DEBUG, ("time now = %s", utct2str(&(ut2))));
#endif
					(*next_tk) = tk->tk_next;
					timeout_task(tk);
					continue;
				} else {
					timeout_tmp = (int) tk->tk_timeout - timenow;
					if(((*secs_p) == NOTOK) || ((*secs_p) > timeout_tmp)) {
						(*secs_p) = timeout_tmp;
					}
				}
			}

			next_tk = &(tk->tk_next);
		}

		if(cn->cn_state == CN_OPEN) {
			next_tk = &(cn->cn_tasklist);
			for(tk=cn->cn_tasklist; tk!=NULLTASK; tk=(*next_tk)) {
				next_tk = &(tk->tk_next);

				if(tk->tk_state == TK_ACTIVE) {
					if(   (ret_tk == NULLTASK)
							|| (tk->tk_prio > ret_tk->tk_prio)
							|| (   (tk->tk_prio == ret_tk->tk_prio)
								   && (   (!ret_tk->tk_timed)
										  || (   (tk->tk_timed)
												 && (tk->tk_timeout < ret_tk->tk_timeout)
											 )
									  )
							   )
					  ) {
						ret_tk = tk;
					}
				}

				if(tk->tk_state == TK_SUSPEND) {
					/*
					*  A task suspended to allow the network to be polled.
					*  Set suspended to force polling.
					*/
					tk->tk_state = TK_ACTIVE;
					suspended = TRUE;
				}
			}

			if(cn->cn_tasklist == NULLTASK) {
				if(cn->cn_initiator) {
					if(cn->cn_operlist == NULLOPER) {
						if((cn->cn_last_used + conn_timeout) <= timenow) {
							do_timeout = TRUE;
						} else {
							timeout_tmp = (int) (cn->cn_last_used + conn_timeout) - timenow;
							if(((*secs_p) == NOTOK) || ((*secs_p) > timeout_tmp)) {
								(*secs_p) = timeout_tmp;
							}
						}
					} else {
						timeout_tmp = conn_timeout;	/* safety catch */
						if ((tk = cn->cn_operlist->on_task) != NULLTASK) {
							if (tk->tk_timed) {
								timeout_tmp = (int) tk->tk_timeout - timenow;
								if (timeout_tmp < 0)
									timeout_tmp = 0;
							}
						}
						if(((*secs_p) == NOTOK) || ((*secs_p) > timeout_tmp)) {
							(*secs_p) = timeout_tmp;
						}
						cn->cn_last_used = timenow;
					}
				}
			} else {
				cn->cn_last_used = timenow;
				process_edbs = FALSE;
			}
		} else  {
			if((cn->cn_last_used + nsap_timeout) <= timenow) {
				if ((cn->cn_state == CN_CONNECTING1) || (cn->cn_state == CN_CONNECTING2))
					conn_retry(cn,1);
				else if (cn->cn_state == CN_CLOSING) {
					if (conn_release_retry(cn) == NOTOK) {
						/* had its chance - abort */
						conn_rel_abort (cn);
						do_ds_unbind(cn);
						conn_extract(cn);
					}
				} else if ( (cn->cn_state == CN_OPENING)
							|| (cn->cn_state == CN_PRE_OPENING) ) {
					/* something started to associate - then gave up !!! */
					conn_rel_abort (cn);
					conn_extract (cn);
				}
				(*secs_p) = nsap_timeout;
			} else {
				timeout_tmp = (int) (cn->cn_last_used + nsap_timeout) - timenow;
				if(((*secs_p) == NOTOK) || ((*secs_p) > timeout_tmp)) {
					(*secs_p) = timeout_tmp;
				}
			}
		}

		if(do_timeout) {
			LLOG(log_dsap, LLOG_TRACE, ("Timing out connection %d",cn->cn_ad));
			if (conn_release(cn) == NOTOK) {
				(*secs_p) = nsap_timeout;
				conns_used++;
			}
		} else {
			conns_used++;
		}
	}

	/*
	*  Open the connection with the highest priority operation
	*  waiting on it...
	*
	*  Get DSA Info operations are highest priority, followed by
	*  BIND_COMPARE, and X500, and finally GetEDB operations.
	*/

	next_cn = &(connwaitlist);
	for(cn=connwaitlist; cn!=NULLCONN; cn=(*next_cn)) {
		if(conns_used >= MAX_CONNS)
			break;

		for(on=cn->cn_operlist; on!=NULLOPER; on=on->on_next_conn) {
			if(on->on_type == ON_TYPE_GET_DSA_INFO) {
				(*next_cn) = cn->cn_next;
				if(conn_request(cn) == OK) {
					conns_used++;
					cn->cn_next = connlist;
					connlist = cn;
					cn->cn_last_used = timenow;
					/* Do something with the operations */
				} else {
					/* Do something with the operations */
				}
				break;
			}
		}
		if(on == NULLOPER)
			next_cn = &(cn->cn_next);
	}

	next_cn = &(connwaitlist);
	for(cn=connwaitlist; cn!=NULLCONN; cn=(*next_cn)) {
		if(conns_used >= (MAX_CONNS - CONNS_RESERVED_DI))
			break;

		for(on=cn->cn_operlist; on!=NULLOPER; on=on->on_next_conn) {
			if(on->on_type != ON_TYPE_GET_EDB) {
				(*next_cn) = cn->cn_next;
				if(conn_request(cn) == OK) {
					conns_used++;
					cn->cn_next = connlist;
					connlist = cn;
					cn->cn_last_used = timenow;
					/* Do something with the operations */
				} else {
					/* Do something with the operations */
				}
				break;
			}
		}
		if(on == NULLOPER)
			next_cn = &(cn->cn_next);
	}

	next_cn = &(connwaitlist);
	for(cn=connwaitlist; cn!=NULLCONN; cn=(*next_cn)) {
		if(conns_used >= (MAX_CONNS - CONNS_RESERVED_DI - CONNS_RESERVED_X500))
			break;

		(*next_cn) = cn->cn_next;
		if(conn_request(cn) == OK) {
			conns_used++;
			cn->cn_next = connlist;
			connlist = cn;
			cn->cn_last_used = timenow;
			/* Do something with the operations */
		} else {
			/* Do something with the operations */
		}
	}

	if(process_edbs && !quipu_shutdown) {
		/*
		*  Nothing is happening that would be disturbed by writing back
		*  a retrieved EDB so it is a good time to process them.
		*/

		if (!get_edb_ops && pending_ops) {

			get_edb_ops = pending_ops;
			pending_ops = NULLOPER;

			if(oper_chain(get_edb_ops) != OK) {
				LLOG(log_dsap, LLOG_TRACE, ("Could not chain a pending operation"));
				(*secs_p) = 0;  /* service network and then try next one */

				pending_ops = get_edb_ops -> on_next_task;
				get_edb_ops -> on_next_task = NULLOPER;
				oper_free(get_edb_ops);
				get_edb_ops = NULLOPER;
			}
		} else if (get_edb_ops) {
			if (get_edb_ops->on_state == ON_COMPLETE) {
				if (get_edb_ops->on_type == ON_TYPE_GET_EDB)
					process_edb(get_edb_ops,&newop);
				else { /* ON_TYPE_SHADOW */
					process_shadow(get_edb_ops);
					ds_res_free (&get_edb_ops->
								 on_resp.di_result.dr_res.dcr_dsres);
				}

				if (newop) {
					newop->on_next_task = get_edb_ops->on_next_task;
					get_edb_ops->on_next_task = NULLOPER;

					oper_conn_extract(get_edb_ops);
					oper_free(get_edb_ops);

					if (oper_send_invoke (newop) != OK) {
						LLOG(log_dsap, LLOG_EXCEPTIONS,
							 ("oper_send getedb next failed"));
						oper_free (newop);
						get_edb_ops = NULLOPER;
					}
					get_edb_ops = newop;

				} else  if (get_edb_ops) {

					pending_ops = get_edb_ops->on_next_task;
					get_edb_ops->on_next_task = NULLOPER;

					oper_conn_extract(get_edb_ops);
					oper_free(get_edb_ops);

					get_edb_ops = NULLOPER;
				}
				(*secs_p) = 0; /* Schedule next one ! */

			} else if (get_edb_ops->on_state == ON_ABANDONED) {
				LLOG (log_dsap,LLOG_TRACE,("Get edb has been abandoned"));

				pending_ops = get_edb_ops->on_next_task;
				get_edb_ops->on_next_task = NULLOPER;

				oper_free(get_edb_ops);

				get_edb_ops = NULLOPER;
				(*secs_p) = 0; /* Schedule next one ! */
			}

		} else if (startup_update) {
			/* see if cache timer has expired - if so resend edb ops... */
			if ( (timenow - lastedb_update) >= slave_timeout )
				slave_update();
		}
	}

	if ((get_edb_ops == NULLOPER) && startup_update ) {
		/* make sure we are awake for the next EDB update */
		if ((timeout_tmp = lastedb_update + slave_timeout - timenow) >= 0)
			if (((*secs_p) == NOTOK) || ((*secs_p) > timeout_tmp))
				(*secs_p) = timeout_tmp;
	}

	if(suspended) {
		/*
		*  A task suspended in order for the network to be checked.
		*  Force this to happen by setting the selected task to NULL
		*  and the polling time of the network to 0 secs.
		*/
		ret_tk = NULLTASK;
		(*secs_p) = 0;
	}

	for(cn=connwaitlist; cn!=NULLCONN; cn=cn->cn_next)
		xi++;

	/* If someting is waiting, see if we can shut a connection down */
	/* Make arbitary choice for now */
	for(cn=connlist; (xi!=0 || quipu_shutdown) && (cn!=NULLCONN); cn=cn_tmp) {
		cn_tmp = cn->cn_next;

		if ((cn->cn_state == CN_OPEN)
				&& (cn->cn_tasklist == NULLTASK)
				&& (cn->cn_initiator)
				&& (cn->cn_operlist == NULLOPER)) {

			LLOG(log_dsap, LLOG_TRACE, ("Releasing connection %d early (%d waiting)",cn->cn_ad,xi));

			if (conn_release(cn) == NOTOK)
				conns_used++;
			else
				xi--;

			(*secs_p) = 0;	/* let connection be re-used */
		}
	}

#ifndef NO_STATS
	if ( (timenow - last_log_close) >= LOGOPENTIME ) {
		 ll_close (log_stat);
		last_log_close = timenow;
	} else {
		if ( (ret_tk == NULLTASK) && (*secs_p >= LOGOPENTIME))
			*secs_p = LOGOPENTIME;	/* Wake to close log! */
	}
#endif

	if(process_edbs && quipu_shutdown)
		*secs_p = NOTOK;

	return(ret_tk);
}