Skip to content

Commit

Permalink
foreach_conns_except because i can't make boost lambda behave..
Browse files Browse the repository at this point in the history
  • Loading branch information
RJ committed May 29, 2009
1 parent 74ed16b commit 162ed96
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 49 deletions.
31 changes: 21 additions & 10 deletions app/main.cpp
Expand Up @@ -4,14 +4,16 @@
#include <boost/asio.hpp>
#include <boost/thread/thread.hpp>
#include <boost/algorithm/string.hpp>

#include "boost/lambda/lambda.hpp"
#include <boost/lambda/if.hpp>

#include "libf2f/router.h"
#include "libf2f/protocol.h"

using namespace std;
using namespace libf2f;


void iorun( boost::asio::io_service * ios )
{
ios->run();
Expand All @@ -31,13 +33,14 @@ int main(int argc, char **argv)
Protocol p;
short port = atoi(argv[1]);
cout << "Listening on port " << port << endl;
boost::asio::ip::tcp::acceptor acc(
ios,
boost::asio::ip::tcp::endpoint(
boost::asio::ip::tcp::v4(),
port)
boost::shared_ptr<boost::asio::ip::tcp::acceptor> accp(
new boost::asio::ip::tcp::acceptor
(ios, boost::asio::ip::tcp::endpoint(
boost::asio::ip::tcp::v4(),
port)
)
);
Router r(acc, &p);
Router r(accp, &p);

boost::thread t( boost::bind(&iorun, &ios) );

Expand Down Expand Up @@ -66,12 +69,20 @@ int main(int argc, char **argv)

if(parts[0] == "pingall")
{
message_ptr ping = PingMessage::factory();
r.foreach_conns( boost::bind(&Connection::async_write, _1, ping) );
message_ptr ping = message_ptr(new PingMessage());
r.send_all(ping);
}

if(parts[0] == "query" && parts.size() == 2)
{
message_ptr search = message_ptr(new GeneralMessage(QUERY, parts[1]) );
r.send_all(search);
}

if(parts[0] == "quit") break;
}

ios.stop();
r.stop();
t.join();
return 0;
}
12 changes: 9 additions & 3 deletions include/libf2f/connection.h
Expand Up @@ -4,6 +4,7 @@
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/thread/thread.hpp>
Expand All @@ -19,6 +20,7 @@ namespace libf2f {

class Connection;
typedef boost::shared_ptr<Connection> connection_ptr;
typedef boost::weak_ptr<Connection> connection_ptr_weak;

/// This class represents a Connection to one other libf2f user.
/// it knows how to marshal objects to and from the wire protocol
Expand Down Expand Up @@ -60,7 +62,8 @@ class Connection

size_t drain_writeq( std::deque< message_ptr > & out );

void set_message_received_cb( boost::function< void(message_ptr, connection_ptr) > cb );
void push_message_received_cb( boost::function< void(message_ptr, connection_ptr) > cb );
void pop_message_received_cb();

std::string str() const;

Expand All @@ -74,13 +77,16 @@ class Connection

/// Stateful stuff the protocol handler/servent will set:
std::string m_username; // username of user at end of Connection
bool m_authed;
//bool m_authed;
bool m_sending;

std::vector< boost::function<void(message_ptr, connection_ptr)> > m_message_received_cbs;
boost::mutex m_message_received_cb_mutex; // protects the above

boost::function< void(message_ptr, connection_ptr) > m_message_received_cb;
boost::function< void(connection_ptr) > m_fin_cb; // call when we die.

bool m_shuttingdown;

};

} //ns
Expand Down
52 changes: 44 additions & 8 deletions include/libf2f/message.h
Expand Up @@ -75,7 +75,6 @@ class Message
: m_payload(0)
{
m_header = header;
m_guid = std::string(header.guid, 36);
//std::cout << "CTOR Msg(" << m_guid << ")" << std::endl;
}

Expand All @@ -101,10 +100,23 @@ class Message
virtual const short ttl() const { return m_header.ttl; }
virtual const short hops() const { return m_header.hops; }
virtual const boost::uint32_t length() const { return ntohl(m_header.length); }
virtual const std::string& guid() const { return m_guid; }
virtual const std::string& guid() const
{
if( m_guid.empty() )
{
m_guid = std::string(m_header.guid, 36);
}
return m_guid;
}
// payload
virtual const char * payload() const { return m_payload; }
virtual char * payload() { return m_payload; }
/// sucks to have to do this really, jsonspirit needs a string or stream:
virtual std::string payload_str() const
{
std::string s(m_payload, length());
return s;
}

virtual size_t malloc_payload()
{
Expand Down Expand Up @@ -132,16 +144,18 @@ class Message
return buffers;
}

private:
protected:
message_header m_header;
std::string m_guid;
mutable std::string m_guid;
char * m_payload;
};



class PongMessage : public Message
{
public:
static boost::shared_ptr<Message> factory()
PongMessage()
{
message_header h;
memcpy( &h.guid, std::string(GENUUID).data(), 36 );
Expand All @@ -150,26 +164,47 @@ class PongMessage : public Message
h.ttl = 1;
h.hops = 0;
h.length = 0;
return boost::shared_ptr<Message>(new Message( h ));
m_header = h;
m_payload = 0;
}
};

class PingMessage : public Message
{
public:
static boost::shared_ptr<Message> factory()
PingMessage()
{
message_header h;
memcpy( &h.guid, std::string(GENUUID).data(), 36 );
//h.guid = GENUUID;
h.type = PING;
h.ttl = 1;
h.hops = 0;
h.length = 0;
return boost::shared_ptr<Message>(new Message( h ));
m_header = h;
m_payload = 0;
}
};

class GeneralMessage : public Message
{
public:
GeneralMessage(const char msgtype, const std::string& body)
{
message_header h;
memcpy( &h.guid, std::string(GENUUID).data(), 36 );
//h.guid = GENUUID;
h.type = msgtype;
h.ttl = 1;
h.hops = 0;
h.length = htonl( body.length() );
m_header = h;
malloc_payload();
memcpy( m_payload, body.data(), body.length() );
}
};

/*
/// File transfer/streaming msgs are special in that they have an additional header describing the payload (just the sid)
Expand All @@ -195,6 +230,7 @@ class DataMessage : public Message
private:
mutable std::string m_sid;
};
*/

}
#endif
7 changes: 6 additions & 1 deletion include/libf2f/protocol.h
Expand Up @@ -10,6 +10,8 @@ class Protocol
{
public:
Protocol();

virtual ~Protocol(){}

virtual void set_router(Router * r) { m_router = r; }

Expand All @@ -19,10 +21,13 @@ class Protocol
/// called when we opened a socket to a remote servent
virtual void new_outgoing_connection( connection_ptr conn );

/// called on a disconnection, for whatever reason
virtual void connection_terminated( connection_ptr conn ){}

/// we received a msg from this connection
virtual void message_received( message_ptr msgp, connection_ptr conn );

private:
protected:
Router * m_router;
};

Expand Down
23 changes: 18 additions & 5 deletions include/libf2f/router.h
Expand Up @@ -5,6 +5,8 @@
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
#include "boost/lambda/lambda.hpp"
#include <boost/lambda/if.hpp>
#include <iostream>
#include <vector>

Expand All @@ -17,8 +19,6 @@ class Protocol;


/// aka servent - responsible for managing connections
/// it will authenticate connections before creating a Connection
/// object and starting to send/recv data using flow control mechanism.
class Router
{
public:
Expand All @@ -28,8 +28,10 @@ class Router
/// acceptor(io_service,
/// boost::asio::ip::tcp::endpoint(
/// boost::asio::ip::tcp::v4(), port) )
Router( boost::asio::ip::tcp::acceptor & acc, Protocol * p );
Router( boost::shared_ptr<boost::asio::ip::tcp::acceptor> accp, Protocol * p );

/// calls io_service::stop on acceptor.
void stop();

/// Handle completion of a accept operation.
void handle_accept(const boost::system::error_code& e, connection_ptr conn);
Expand All @@ -42,24 +44,35 @@ class Router
boost::asio::ip::tcp::endpoint &endpoint,
connection_ptr conn);

/// connection terminated for any reason
void connection_terminated( connection_ptr conn );

/// Default message recvd callback
void message_received( message_ptr msgp, connection_ptr conn );

/// apply function to all registered connections
void foreach_conns( boost::function<void(connection_ptr)> );

/// apply function to all registered connections *except* conn
void foreach_conns_except( boost::function<void(connection_ptr)> fun, connection_ptr conn );

/// send msg to all registered connections
void send_all( message_ptr msgp );

std::string connections_str();
private:
/// Router keeps track of connections:
void register_connection( connection_ptr conn );
void unregister_connection( connection_ptr conn );
void connections_str();


/// all connections:
std::vector< connection_ptr > m_connections;
boost::mutex m_connections_mutex; // protects connections

/// The acceptor object used to accept incoming socket connections.
boost::asio::ip::tcp::acceptor & m_acceptor;
boost::shared_ptr<boost::asio::ip::tcp::acceptor> m_acceptor;

/// protocol implementation
Protocol * m_protocol;
/// thread that enforces flow-control and sends outgoing msgs
Expand Down

0 comments on commit 162ed96

Please sign in to comment.