#include <iostream>
#include <list>
#ifdef CCXX_NAMESPACES
#endif
class ts_list_item;
typedef list<ts_list_item *> ts_list;
class ts_list_head {
public:
ts_list list_o_items;
ts_list_head()
: linkmutex(), list_o_items() {
}
void RemoveListItem( ts_list_item * li );
void InsertListItem( ts_list_item * li );
virtual void ListDepleted() {
}
virtual ~ts_list_head() {
}
};
class ts_list_item {
public:
ts_list::iterator linkpoint;
ts_list_head * listhead;
virtual ~ts_list_item() {
listhead->RemoveListItem( this );
}
ts_list_item( ts_list_head * head ) {
listhead = head;
head->InsertListItem( this );
}
};
void ts_list_head::RemoveListItem( ts_list_item * li )
{
bool is_empty;
linkmutex.enterMutex();
list_o_items.erase( li->linkpoint );
is_empty = list_o_items.empty();
linkmutex.leaveMutex();
if ( is_empty ) {
ListDepleted();
}
}
void ts_list_head::InsertListItem( ts_list_item * li )
{
linkmutex.enterMutex();
list_o_items.push_front( li );
li->linkpoint = list_o_items.begin();
linkmutex.leaveMutex();
}
class ChatterSession :
public virtual ts_list_item {
public:
enum { size_o_buf = 2048 };
virtual ~ChatterSession() {
cerr << "ChatterSession deleted !\n";
}
ChatterSession(
ts_list_head * head
) :
ts_list_item( head ) {
cerr << "ChatterSession Created\n";
cerr << "connecting from " << ia.getHostname() <<
":" << port << endl;
setCompletion( false );
setTimer( 100000 );
attach(svc);
}
virtual void expired() {
cerr << "ChatterSession Expired\n";
delete this;
}
virtual void pending() {
cerr << "Pending called\n";
setTimer( 100000 );
try {
int len;
unsigned int total = 0;
char buf[ size_o_buf ];
while ( (len = receive(buf, sizeof(buf) )) > 0 ) {
total += len;
cerr << "Read '";
cerr.write( buf, len );
cerr << "'\n";
bool sent = false;
listhead->linkmutex.enterMutex();
for (
ts_list::iterator iter = listhead->list_o_items.begin();
iter != listhead->list_o_items.end();
iter ++
) {
ChatterSession * sess =
dynamic_cast< ChatterSession * >( * iter );
if ( sess != this ) {
sess->send( buf, len );
sent = true;
}
}
listhead->linkmutex.leaveMutex();
if ( ! sent ) {
send(
( void * ) "No one else listening\n",
sizeof( "No one else listening\n" ) - 1
);
send( buf, len );
}
}
if (total == 0) {
cerr << "Broken connection!\n" << endl;
delete this;
}
}
catch ( ... ) {
cerr << "Socket port write sent an exception !\n";
}
}
virtual void disconnect() {
cerr << "ChatterSession disconnected!\n";
delete this;
}
};
class ChatterThread;
class CCExec : public virtual ts_list_head {
public:
ChatterThread * my_Chatter;
CCExec():my_Chatter(NULL) {
}
virtual void ListDepleted();
virtual ~CCExec();
int RunApp( char * hn = (char *)"localhost" );
};
public:
CCExec * exec;
void run () {
while ( 1 ) {
try {
new ChatterSession(
exec->service,
exec
);
}
catch ( ... ) {
cerr << "ChatterSession create failed\n";
exit();
}
}
}
ChatterThread(
int port,
CCExec * inexec
exec( inexec ) {
start();
}
};
CCExec::~CCExec()
{
if ( my_Chatter ) delete my_Chatter;
delete service;
}
int CCExec::RunApp( char * hn )
{
if ( machine.isInetAddress() == false ) {
cerr << "machine is not address" << endl;
}
cerr << "machine is " << machine.getHostname() << endl;
try {
my_Chatter = new ChatterThread(
machine,
3999,
this
);
}
catch ( ... ) {
cerr << "Failed to bind\n";
return false;
}
return true;
}
void CCExec::ListDepleted()
{
}
int main( int argc, char ** argv )
{
CCExec * server;
server = new CCExec();
if ( argc > 1 ) {
server->RunApp( argv[ 1 ] );
} else {
server->RunApp();
}
server->mainsem->wait();
delete server;
return 0;
}