Пример #1
0
// return type
// 事件循环主函数
int 
socket_server_poll(struct socket_server *ss, struct socket_message * result, int * more) {
	for (;;) {
		// 如果需要监测指令
		if (ss->checkctrl) {
			// 如果有指令输入
			if (has_cmd(ss)) {
				// 读入指令并执行对应逻辑
				int type = ctrl_cmd(ss, result);
				if (type != -1) {
					// 正常执行
					clear_closed_event(ss, result, type);
					return type;
				} else
					continue;
			} else {
				ss->checkctrl = 0;
			}
		}
		if (ss->event_index == ss->event_n) {
			// 如果事件循环无可读事件,等待新的事件产生
			// 同时打开指令监测标识
			ss->event_n = sp_wait(ss->event_fd, ss->ev, MAX_EVENT);
			ss->checkctrl = 1;
			if (more) {
				*more = 0;
			}
			ss->event_index = 0;
			if (ss->event_n <= 0) {
				ss->event_n = 0;
				return -1;
			}
		}
		// 读取一个事件
		struct event *e = &ss->ev[ss->event_index++];
		struct socket *s = e->s;
		if (s == NULL) {
			// dispatch pipe message at beginning
			continue;
		}
		switch (s->type) {
		case SOCKET_TYPE_CONNECTING:
			// 返回 SOCKET_OPEN,修改socket为CONNECTED类型
			return report_connect(ss, s, result);
		case SOCKET_TYPE_LISTEN: {
			// 返回 SOCKET_ACCEPT,生成被动套接字
			int ok = report_accept(ss, s, result);
			if (ok > 0) {
				return SOCKET_ACCEPT;
			} if (ok < 0 ) {
				return SOCKET_ERROR;
			}
			// when ok == 0, retry
			break;
		}
		case SOCKET_TYPE_INVALID:
			fprintf(stderr, "socket-server: invalid socket\n");
			break;
		default:
			// 读取数据
			if (e->read) {
				// 如果事件可读
				int type;
				// forward_message_tcp/udp 正常返回 SOCKET_DATA
				if (s->protocol == PROTOCOL_TCP) {
					type = forward_message_tcp(ss, s, result);
				} else {
					type = forward_message_udp(ss, s, result);
					if (type == SOCKET_UDP) {
						// try read again
						--ss->event_index;
						return SOCKET_UDP;
					}
				}
				if (e->write && type != SOCKET_CLOSE && type != SOCKET_ERROR) {
					// 如果同时可写,回滚索引关闭可写标识,等待下一次循环进入可写逻辑
					// Try to dispatch write message next step if write flag set.
					e->read = false;
					--ss->event_index;
				}
				if (type == -1)
					break;				
				return type;
			}
			// 写入数据
			if (e->write) {
				// 如果事件可写
				// 发送链表缓冲区数据
				int type = send_buffer(ss, s, result);
				if (type == -1)
					break;
				return type;
			}
			break;
		}
	}
}
Пример #2
0
// return type
int
socket_server_poll(struct socket_server *ss, struct socket_message * result, int * more) {
    for (;;) {
        if (ss->checkctrl) {
            if (has_cmd(ss)) {
                int type = ctrl_cmd(ss, result);
                if (type != -1) {
                    clear_closed_event(ss, result, type);
                    return type;
                } else
                    continue;
            } else {
                ss->checkctrl = 0;
            }
        }
        if (ss->event_index == ss->event_n) {
            ss->event_n = sp_wait(ss->event_fd, ss->ev, MAX_EVENT);
            ss->checkctrl = 1;
            if (more) {
                *more = 0;
            }
            ss->event_index = 0;
            if (ss->event_n <= 0) {
                ss->event_n = 0;
                return -1;
            }
        }
        struct event *e = &ss->ev[ss->event_index++];
        struct socket *s = e->s;
        if (s == NULL) {
            // dispatch pipe message at beginning
            continue;
        }
        switch (s->type) {
        case SOCKET_TYPE_CONNECTING:
            return report_connect(ss, s, result);
        case SOCKET_TYPE_LISTEN:
            if (report_accept(ss, s, result)) {
                return SOCKET_ACCEPT;
            }
            break;
        case SOCKET_TYPE_INVALID:
            fprintf(stderr, "socket-server: invalid socket\n");
            break;
        default:
            if (e->read) {
                int type;
                if (s->protocol == PROTOCOL_TCP) {
                    type = forward_message_tcp(ss, s, result);
                } else {
                    type = forward_message_udp(ss, s, result);
                    if (type == SOCKET_UDP) {
                        // try read again
                        --ss->event_index;
                        return SOCKET_UDP;
                    }
                }
                if (e->write) {
                    // Try to dispatch write message next step if write flag set.
                    e->read = false;
                    --ss->event_index;
                }
                if (type == -1)
                    break;
                clear_closed_event(ss, result, type);
                return type;
            }
            if (e->write) {
                int type = send_buffer(ss, s, result);
                if (type == -1)
                    break;
                clear_closed_event(ss, result, type);
                return type;
            }
            break;
        }
    }
}