Example #1
0
void bufcase(int x){
	bufstr("Case ");
	char num[10], nidx = 0;
	for(nidx = 0; x; ++nidx, x /= 10) num[nidx] = (x % 10) + '0';
	while(nidx--) bufchar(num[nidx]);
	bufstr(":\n");	
}
Example #2
0
void EpollServer::serve() {

#ifdef THREADED_SERVE
	init_thread();
#endif

	int sfd, s;
	int efd;
	struct epoll_event event;
	struct epoll_event *events;

	sfd = makeSvrSocket();
	if (sfd == -1)
		abort();

	s = make_socket_non_blocking(sfd);
	if (s == -1)
		abort();

	reuseSock(sfd);

	efd = epoll_create(1);
	if (efd == -1) {
		perror("epoll_create");
		abort();
	}

	event.data.ptr = new EpollData(sfd, NULL);
	event.events = EPOLLIN | EPOLLET;
	s = epoll_ctl(efd, EPOLL_CTL_ADD, sfd, &event);
	if (s == -1) {
		perror("epoll_ctl");
		abort();
	}

	/* Buffer where events are returned */
	events = (epoll_event *) calloc(MAX_EVENTS, sizeof event);

	/* The event loop */
	while (1) {

		int n, i;

		n = epoll_wait(efd, events, MAX_EVENTS, -1);

		for (i = 0; i < n; i++) {

			EpollData *edata = (EpollData*) events[i].data.ptr;

			if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP)
					|| (!(events[i].events & EPOLLIN))) {

				/* An error has occured on this fd, or the socket is not
				 ready for reading (why were we notified then?) */
				fprintf(stderr, "epoll error\n");
				close(edata->fd());
				delete edata;
				continue;
			} else if (sfd == edata->fd()) {

				if (_tcp == true) {
					/* We have a notification on the listening socket, which
					 means one or more incoming connections. */
					while (1) {

						sockaddr *in_addr = (sockaddr *) calloc(1,
								sizeof(struct sockaddr));
						socklen_t in_len = sizeof(struct sockaddr);

						int infd = accept(sfd, in_addr, &in_len);
						if (infd == -1) {

							free(in_addr);

							if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {

								/* We have processed all incoming connections. */
								break;
							} else {

								perror("accept");
								break;
							}
						}

						/* fprintf(stdout,
						 "sin_family[%hu], sin_zero[%s], sin_addr.s_addr[%u], sin_port[%hu]\n",
						 in_addr.sin_family, in_addr.sin_zero,
						 in_addr.sin_addr.s_addr, in_addr.sin_port);
						 */

						/*
						 char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
						 getnameinfo(in_addr, in_len, hbuf, sizeof hbuf, sbuf,
						 sizeof sbuf, 0);

						 if (s == 0) {

						 printf("Accepted connection on descriptor %d "
						 "(host=%s, _port=%s)\n", infd, hbuf, sbuf);
						 }*/

						/* Make the incoming socket non-blocking and add it to the
						 list of fds to monitor. */
						s = make_socket_non_blocking(infd);
						if (s == -1) {

							free(in_addr);
							abort();
						}

						reuseSock(infd);

						event.data.ptr = new EpollData(infd, in_addr);
						event.events = EPOLLIN | EPOLLET;
						s = epoll_ctl(efd, EPOLL_CTL_ADD, infd, &event);
						if (s == -1) {

							free(in_addr);
							perror("epoll_ctl");
							abort();
						}
					}
					continue;
				} else {

					int done = 0;

					while (1) {

						char buf[Env::BUF_SIZE];
						memset(buf, 0, sizeof(buf));
						//char *buf = (char*) calloc(Env::BUF_SIZE, sizeof(char));

						sockaddr fromaddr;
						socklen_t sender_len = sizeof(struct sockaddr);
						ssize_t count = recvfrom(edata->fd(), buf, sizeof buf,
								0, &fromaddr, &sender_len);
						//cout << "EpollServer.cpp: serve(): received "<< count << " bytes."<<endl;
						if (count == -1) {

							if (errno != EAGAIN) {

								perror("read");
								done = 1;
							}

						} else if (count == 0) {

							done = 1;
							break;

						} else {

#ifdef BIG_MSG
							bool ready = false;
							string bd = pbrb->getBdStr(sfd, buf, count, ready);

							if (ready) {

#ifdef THREADED_SERVE
								EventData eventData(edata->fd(), bd.c_str(), bd.size(),
										fromaddr);
								_eventQueue.push(eventData);

#else
								_ZProcessor->process(edata->fd(), bd.c_str(),
										fromaddr);
#endif
							}
#endif

#ifdef SML_MSG
#ifdef THREADED_SERVE
							EventData eventData(edata->fd(), buf, sizeof(buf),
									fromaddr);
							_eventQueue.push(eventData);

#else
							string bufstr(buf);
							_ZProcessor->process(edata->fd(), bufstr.c_str(),
									fromaddr);
#endif
#endif
						}

						//memset(buf, 0, sizeof(buf));
						//free(buf);
					}

					/*if (done) {

					 close(edata->fd());
					 delete edata;
					 }*/
				}

			} else {

				if (_tcp == true) {

					/* We have data on the fd waiting to be read. Read and
					 display it. We must read whatever data is available
					 completely, as we are running in edge-triggered mode
					 and won't get a notification again for the same
					 data. */
					int done = 0;

					while (1) {

						char buf[Env::BUF_SIZE];
						memset(buf, 0, sizeof(buf));
						//char *buf = (char*) calloc(Env::BUF_SIZE, sizeof(char));

						ssize_t count = recv(edata->fd(), buf, sizeof(buf), 0);

						if (count == -1) {

							/* If errno == EAGAIN, that means we have read all
							 data. So go back to the main loop. */
							if (errno != EAGAIN) {

								perror("read");
								done = 1;
							} /*else {

							 printf(
							 "Closed connection on descriptor %d, -1<--recv\n",
							 edata->fd());

							 close(edata->fd());
							 delete edata;
							 }*/
							break;
						} else if (count == 0) {

							/* End of file. The remote has closed the
							 connection. */
							done = 1;
							break;
						} else {

#ifdef BIG_MSG
							bool ready = false;
							string bd = pbrb->getBdStr(sfd, buf, count, ready);

							if (ready) {

#ifdef THREADED_SERVE
								EventData eventData(edata->fd(), bd.c_str(), bd.size(),
										*edata->sender());
								_eventQueue.push(eventData);
#else
								_ZProcessor->process(edata->fd(), bd.c_str(),
										*edata->sender());
#endif
							}
#endif

#ifdef SML_MSG
#ifdef THREADED_SERVE
							EventData eventData(edata->fd(), buf, sizeof(buf),
									*edata->sender());
							_eventQueue.push(eventData);
#else
							string bufstr(buf);
							_ZProcessor->process(edata->fd(), bufstr.c_str(),
									*edata->sender());
#endif
#endif
						}

						//memset(buf, 0, sizeof(buf));
						//free(buf);
					}

					if (done) {

						/*printf("Closed connection on descriptor %d, done.\n",
						 edata->fd());*/

						/* Closing the descriptor will make epoll remove it
						 from the set of descriptors which are monitored. */
						close(edata->fd());
						delete edata;
					}
				} //if TCP == true
			}
		}
	}

	free(events);

	close(sfd);

	EpollData *edata = (EpollData*) event.data.ptr;
	delete edata;
}