Ejemplo n.º 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)
					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->write) {
				int type = send_buffer(ss, s, result);
				if (type == -1)
					break;
				return type;
			}
			if (e->read) {
				int type = forward_message(ss, s, result);
				if (type == -1)
					break;
				return type;
			}
			break;
		}
	}
}
Ejemplo n.º 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:
			// 返回 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;
		}
	}
}
Ejemplo n.º 3
0
int
silly_socket_poll()
{
        int err;
        sp_event_t *e;
        struct socket *s;
        struct silly_socket *ss = SSOCKET;
        eventwait(ss);
        err = cmd_process(ss);
        if (err < 0)
                return -1;
        if (err >= 1)
                clear_socket_event(ss);
        while (ss->eventindex < ss->eventcount) {
                int ei = ss->eventindex++;
                e = &ss->eventbuff[ei];
                s = (struct socket *)SP_UD(e);
                if (s == NULL)                  //the socket event has be cleared
                        continue;
                switch (s->type) {
                case STYPE_LISTEN:
                        assert(SP_READ(e));
                        report_accept(ss, s);
                        continue;
                case STYPE_CONNECTING:
                        s->type = STYPE_SOCKET;
                        report_connected(ss, s);
                        continue;
                case STYPE_RESERVE:
                        fprintf(stderr, "[socket] poll reserve socket\n");
                        continue;
                case STYPE_HALFCLOSE:
                case STYPE_SOCKET:
                case STYPE_UDPBIND:
                        break;
                case STYPE_CTRL:
                        continue;
                default:
                        fprintf(stderr, "[socket] poll: unkonw socket type:%d\n", s->type);
                        continue;
                }

                if (SP_ERR(e)) {
                        report_close(ss, s, 0);
                        delsocket(ss, s);
                        continue;
                }
                if (SP_READ(e)) {
                        switch (s->protocol) {
                        case PROTOCOL_TCP:
                                err = forward_msg_tcp(ss, s);
                                break;
                        case PROTOCOL_UDP:
                                err = forward_msg_udp(ss, s);
                                break;
                        default:
                                fprintf(stderr, "[socket] poll: unsupport protocol:%d\n", s->protocol);
                                continue;
                        }
                        //this socket have already occurs error, so ignore the write event
                        if (err < 0)
                                continue;
                }
                if (SP_WRITE(e)) {
                        if (s->protocol == PROTOCOL_TCP)
                                send_msg_tcp(ss, s);
                        else
                                send_msg_udp(ss, s);
                }
        }
        return 0;
}
Ejemplo n.º 4
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;
        }
    }
}
Ejemplo n.º 5
0
int socket_server::poll(struct socket_message * result, int * more)
{
    for ( ; ; ) {
        if (checkctrl) {
            if (has_cmd()) {
                int type = ctrl_cmd(result);
                if (type != -1) {
                    clear_closed_event(result, type);
                    return type;
                } else 
                {
                    continue;
                }
            } else {
                checkctrl = 0;
            }
        }
        if (event_index == event_n) {
            event_n = event_fd.wait(ev, MAX_EVENT);
            checkctrl = 1;
            if (more) {
                *more = 0;
            }
            event_index = 0;
            if (event_n <= 0) {
                event_n = 0;
                return -1;
            }
        }
        struct event * e = &ev[event_index++];
        struct socket * s = (struct socket *)e->s;
        if (s == nullptr) {
            continue;
        }
        switch (s->type) {
            case SOCKET_TYPE_CONNECTING:
                printf("********connect ing*********\n");
                return report_connect(s, result);
            case SOCKET_TYPE_LISTEN:
                printf("********new client connect*********\n");
                if (report_accept(s, result)) {
                    return SOCKET_ACCEPT;
                }
                break;
            case SOCKET_TYPE_INVALID:
                fprintf(stderr, "socket-server: invalid socket \n");
                break;
            default:
                if (e->read) {
                    int type = -1;
                    if (s->protocol == PROTOCOL_TCP) {
                        type = forward_message_tcp(s, result);
                    }
                    if (e->write) {
                        e->read = false;
                        --event_index;
                    }
                    if (type == -1) {
                        break;
                    }
                    clear_closed_event(result, type);
                    return type;
                }
                if (e->write) {
                    int type = send_buffer(s, result);
                    if (type == -1)
                        break;
                    clear_closed_event(result, type);
                    return type;
                }
                break;
        }
    }
}