<commit_before>/* -*- C++ -*-
 * (c) 2004 <NAME> <<EMAIL>>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 2.1
 * Refer to the file "COPYING" for details.
 */

#include <boost/bind.hpp>
#include <boost/intrusive_ptr.hpp>

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>

#include <tscb/ref>
#include <tscb/atomic>
#include <tscb/ioready>

class echo {
public:
	echo(tscb::ioready_service *service, int _fd);
	~echo(void);
	
	inline void pin(void) {refcount++;}
	inline void release(void) {if (!--refcount) delete this;}
	
	tscb::atomic refcount;
private:
	void data(int event);
	void destroy(void);
	
	int fd;
	tscb::ioready_callback link;
	tscb::ioready_service *service;
};

static inline void intrusive_ptr_add_ref(echo *e) throw()
{
	e->refcount++;
}
static inline void intrusive_ptr_release(echo *e) throw()
{
	if (!--e->refcount) delete e;
}

class acceptor {
public:
	acceptor(tscb::ioready_service *service, int _fd);
	
	tscb::atomic refcount;
private:
	void connection_request(int event);
	
	int fd;
	tscb::ioready_callback link;
	tscb::ioready_service *service;
};

static inline void intrusive_ptr_add_ref(acceptor *a) throw()
{
	a->refcount++;
}
static inline void intrusive_ptr_release(acceptor *a) throw()
{
	if (!--a->refcount) delete a;
}

echo::echo(tscb::ioready_service *_service, int _fd)
	: fd(_fd), service(_service)
{
	int flags=fcntl(fd, F_GETFL);
	flags |= O_NONBLOCK;
	fcntl(fd, F_SETFL, flags);
	
	link=service->watch(boost::bind(&echo::data, boost::intrusive_ptr<echo>(this), _1),
		fd, tscb::EVMASK_INPUT);
	//link=service->watch<echo, &echo::data, &echo::destroy>
	//	(fd, tscb::EVMASK_INPUT, this);
}

echo::~echo(void)
{
	printf("connection closed\n");
	close(fd);
}

void echo::data(int event)
{
	char buffer[16384];
	int n;
	do {
		n=read(fd, buffer, 16384);
		if (n<0) {
			if (errno==EAGAIN) break;
		}
		if (n<=0) {
			printf("connection closed by client\n");
			link->cancel();
			break;
		}
		write(1, buffer, n);
		write(fd, buffer, n);
	} while(n==16384);
}

acceptor::acceptor(tscb::ioready_service *_service, int _fd)
	: fd(_fd), service(_service)<commit_msg>Make tcpserver demo compilable again<commit_after>/* -*- C++ -*-
 * (c) 2004 <NAME> <<EMAIL>>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 2.1
 * Refer to the file "COPYING" for details.
 */

#include <boost/bind.hpp>
#include <boost/intrusive_ptr.hpp>

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>

#include <tscb/atomic>
#include <tscb/ioready>

class echo {
public:
	echo(tscb::ioready_service *service, int _fd);
	~echo(void);
	
	inline void pin(void) {refcount++;}
	inline void release(void) {if (!--refcount) delete this;}
	
	tscb::atomic refcount;
private:
	void data(int event);
	void destroy(void);
	
	int fd;
	tscb::ioready_callback link;
	tscb::ioready_service *service;
};

static inline void intrusive_ptr_add_ref(echo *e) throw()
{
	e->refcount++;
}
static inline void intrusive_ptr_release(echo *e) throw()
{
	if (!--e->refcount) delete e;
}

class acceptor {
public:
	acceptor(tscb::ioready_service *service, int _fd);
	
	tscb::atomic refcount;
private:
	void connection_request(int event);
	
	int fd;
	tscb::ioready_callback link;
	tscb::ioready_service *service;
};

static inline void intrusive_ptr_add_ref(acceptor *a) throw()
{
	a->refcount++;
}
static inline void intrusive_ptr_release(acceptor *a) throw()
{
	if (!--a->refcount) delete a;
}

echo::echo(tscb::ioready_service *_service, int _fd)
	: fd(_fd), service(_service)
{
	int flags=fcntl(fd, F_GETFL);
	flags |= O_NONBLOCK;
	fcntl(fd, F_SETFL, flags);
	
	link=service->watch(boost::bind(&echo::data, boost::intrusive_ptr<echo>(this), _1),
		fd, tscb::EVMASK_INPUT);
}

echo::~echo(void)
{
	printf("connection closed\n");
	close(fd);
}

void echo::data(int event)
{
	char buffer[16384];
	int n;
	do {
		n=read(fd, buffer, 16384);
		if (n<0) {
			if (errno==EAGAIN) break;
		}
		if (n<=0) {
			printf("connection closed by client\n");
			link->cancel();
			break;
		}
		write(1, buffer, n);
		write(fd, buffer, n);
	} while(n==16384);
}

acceptor::acceptor(tscb::ioready_service *_service, int _fd)
	: fd(_fd), service(_service)
{'fraction_non_alphanumeric': 0.16553238199780462, 'fraction_numerical': 0.010976948408342482, 'mean_word_length': 4.963350785340314, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 50, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '63344', 'n_tokens_mistral': 1857, 'n_tokens_neox': 1787, 'n_words': 425}