Beispiel #1
0
static void sock_handle_write(int fd, void *data)
{
	if(!data) 
		return;
	
	int error = 0;
	struct mstate_write *wstate = data;
	assert(fd == wstate->fd);
	
	int size_need = wstate->size - wstate->offset;
	int size_write = write(fd, wstate->buf + wstate->offset, size_need);
	debug("sock_handle_write fd %d, offset %d, size %d\n", fd, wstate->offset, wstate->size);
	if(size_write == -1) {
		warning("sock_handle_write(%s)\n", strerror(errno));
		if(ignore_error(errno)) {
			sock_set_event(fd, SOCK_EVENT_WR);
			sock_register_event(fd, NULL, NULL, sock_handle_write, wstate);
		}
		else {
			error = 1;
			WPF *handle = wstate->callback;
			void *data = wstate->data;
			int res = wstate->offset;
			
			safe_free(wstate->buf);
			safe_free(wstate);
		
			handle(error, data, res);
		}
		return;
	}
	
	wstate->offset += size_write;

	if(wstate->offset < wstate->size)  {
		sock_set_event(fd, SOCK_EVENT_WR);
		sock_register_event(fd, NULL, NULL, sock_handle_write, wstate);
	}
	else {
		WPF *handle = wstate->callback;
		void *data = wstate->data;
		int res = wstate->offset;
		safe_free(wstate->buf);
		safe_free(wstate);
		
		handle(0, data, res);
	}
}
Beispiel #2
0
void sock_write(int fd, char *buf, int size, WPF *callback, void *data, int use_event)
{
	int size_write;
	struct mstate_write *wstate = calloc(1, sizeof(*wstate));
	if(wstate == NULL) {
		error("sock_write %s\n", strerror(errno));
		abort();
	}

	wstate->callback = callback;
	wstate->data = data;
	wstate->fd = fd;
	wstate->buf = calloc(1, size); /* remind to free */
	memcpy(wstate->buf, buf, size);
	wstate->offset = 0;
	wstate->size = size;
	
	if(use_event) {
		sock_event_append(EVENT_WRITE, fd, sock_handle_write, wstate);
		sock_set_event(fd, SOCK_EVENT_WR);
		if(fd_table[fd].ops.write_handler != NULL) {
			debug("warning! fd %d write handler is not null\n", fd);
			return;
		}
		sock_register_event(fd, NULL, NULL, sock_event_run, NULL);
		return;
	}

	sock_handle_write(fd, wstate);
}
Beispiel #3
0
static void sock_handle_sendfile(int fd, void *data)
{
	int error = 0;
	struct fstate_write *fs = data;

	assert(fs->out_fd == fd);
	
	int size_need = fs->size - fs->size_sent;
	int size_write = sendfile(fs->out_fd, fs->in_fd, (off_t *)&fs->offset, size_need);
	int res = 0;

	if(size_write == -1) {
		warning("sock_handle_sendfile fd %d %s\n", fd, strerror(errno));

		if(ignore_error(errno))  {
			sock_set_event(fd, SOCK_EVENT_WR);
			sock_register_event(fd, NULL, NULL, sock_handle_sendfile, fs);
		}
		else {
			s_error("sock_handle_sendfile fd %d %s\n", fd, strerror(errno));
			error = 1;
			WPF *handle = fs->callback;
			void *data = fs->data;
			res = fs->size_sent;
			safe_free(fs);

			handle(error, data, res);
		}
		return;
	}

	fs->size_sent += size_write;

	if(fs->size_sent < fs->size) {
		sock_set_event(fd, SOCK_EVENT_WR);
		sock_register_event(fd, NULL, NULL, sock_handle_sendfile, fs);
	}
	else {
		WPF *handle = fs->callback;
		res = fs->size_sent;
		void *data = fs->data;
		safe_free(fs);

		handle(error, data, res);
	}
}
Beispiel #4
0
void sock_close(int fd) 
{
	assert(fd_table);
	
	if(!fd_table[fd].flags.open)
		return;

	debug("sock_close fd %d\n", fd);	
	sock_set_event(fd, SOCK_EVENT_NO); /* do not need to listen again */
	fd_close(fd);
	close(fd);
}
Beispiel #5
0
static int port__ctl_mod(port_state_t* port_state,
                         SOCKET sock,
                         struct epoll_event* ev) {
  sock_state_t* sock_state = port_find_socket(port_state, sock);
  if (sock_state == NULL)
    return -1;

  if (sock_set_event(port_state, sock_state, ev) < 0)
    return -1;

  port__update_events_if_polling(port_state);

  return 0;
}
Beispiel #6
0
static int port__ctl_add(port_state_t* port_state,
                         SOCKET sock,
                         struct epoll_event* ev) {
  sock_state_t* sock_state = sock_new(port_state, sock);
  if (sock_state == NULL)
    return -1;

  if (sock_set_event(port_state, sock_state, ev) < 0) {
    sock_delete(port_state, sock_state);
    return -1;
  }

  port__update_events_if_polling(port_state);

  return 0;
}
Beispiel #7
0
void sock_event_run(int fd, void *data)
{
	struct fd_t *f = &fd_table[fd];
	int fin = 0;
	struct event *e = f->wqueue;

	debug("sock_event_run fd %d\n", fd);
	if(e == NULL) {
		sock_set_event(fd, SOCK_EVENT_NO);
		return;
	}
	fin = event_exec_one(e);

	if( -1 == fin) {
		if(f->ops.write_handler == NULL) {
			int type = 1;
			sock_register_event(fd, NULL, NULL, sock_event_run, &type);
		}
	}
}
Beispiel #8
0
void sock_init() 
{
	assert(config);
	
	if(fd_table)
		return;
	if(MAX_FD < 20240) 
		warning("sock_init MAX_FD %d, too small\n", MAX_FD);
	fd_table = calloc(MAX_FD, sizeof(*fd_table));
	int listen_fd = -1;
	
	assert(fd_table);

	sock_epoll_init();
	
	listen_fd = sock_listen_open();

	sock_set_event(listen_fd, SOCK_EVENT_RD);
	
	sock_register_event(listen_fd, http_request_accept, NULL, NULL, NULL);
	
	log_debug(__FILE__, __LINE__, "Listen port %d, fd %d\n", ntohs(config->server.port), listen_fd);
}