155 lines
4 KiB
C++
155 lines
4 KiB
C++
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
|
// License: Boost Software License See LICENSE.txt for the full license.
|
|
#ifndef DLIB_SERVER_IOSTREAm_1_
|
|
#define DLIB_SERVER_IOSTREAm_1_
|
|
|
|
#include <iostream>
|
|
#include "server_iostream_abstract.h"
|
|
#include "../logger.h"
|
|
#include "../uintn.h"
|
|
#include "server_kernel.h"
|
|
#include "../sockstreambuf.h"
|
|
#include "../map.h"
|
|
|
|
|
|
namespace dlib
|
|
{
|
|
|
|
class server_iostream : public server
|
|
{
|
|
|
|
/*!
|
|
INITIAL VALUE
|
|
- next_id == 0
|
|
- con_map.size() == 0
|
|
|
|
CONVENTION
|
|
- next_id == the id of the next connection
|
|
- for all current connections
|
|
- con_map[id] == the connection object with the given id
|
|
- m == the mutex that protects the members of this object
|
|
!*/
|
|
|
|
typedef map<uint64,connection*,memory_manager<char>::kernel_2a>::kernel_1b id_map;
|
|
|
|
public:
|
|
server_iostream(
|
|
) :
|
|
next_id(0)
|
|
{}
|
|
|
|
~server_iostream(
|
|
)
|
|
{
|
|
server::clear();
|
|
}
|
|
|
|
protected:
|
|
|
|
void shutdown_connection (
|
|
uint64 id
|
|
)
|
|
{
|
|
auto_mutex M(m);
|
|
if (con_map.is_in_domain(id))
|
|
{
|
|
con_map[id]->shutdown();
|
|
}
|
|
}
|
|
|
|
private:
|
|
|
|
virtual void on_connect (
|
|
std::istream& in,
|
|
std::ostream& out,
|
|
const std::string& foreign_ip,
|
|
const std::string& local_ip,
|
|
unsigned short foreign_port,
|
|
unsigned short local_port,
|
|
uint64 connection_id
|
|
)=0;
|
|
|
|
void on_connect (
|
|
connection& con
|
|
)
|
|
{
|
|
bool my_fault = true;
|
|
uint64 this_con_id;
|
|
try
|
|
{
|
|
sockstreambuf buf(&con);
|
|
std::istream in(&buf);
|
|
std::ostream out(&buf);
|
|
in.tie(&out);
|
|
|
|
// add this connection to the con_map
|
|
{
|
|
auto_mutex M(m);
|
|
this_con_id = next_id;
|
|
connection* this_con = &con;
|
|
con_map.add(this_con_id,this_con);
|
|
this_con_id = next_id;
|
|
++next_id;
|
|
}
|
|
|
|
my_fault = false;
|
|
on_connect(
|
|
in,
|
|
out,
|
|
con.get_foreign_ip(),
|
|
con.get_local_ip(),
|
|
con.get_foreign_port(),
|
|
con.get_local_port(),
|
|
this_con_id
|
|
);
|
|
|
|
// remove this connection from the con_map
|
|
{
|
|
auto_mutex M(m);
|
|
connection* this_con;
|
|
uint64 junk;
|
|
con_map.remove(this_con_id,junk,this_con);
|
|
}
|
|
|
|
}
|
|
catch (std::bad_alloc&)
|
|
{
|
|
// make sure we remove this connection from the con_map
|
|
{
|
|
auto_mutex M(m);
|
|
if (con_map.is_in_domain(this_con_id))
|
|
{
|
|
connection* this_con;
|
|
uint64 junk;
|
|
con_map.remove(this_con_id,junk,this_con);
|
|
}
|
|
}
|
|
|
|
_dLog << LERROR << "We ran out of memory in server_iostream::on_connect()";
|
|
// if this is an escaped exception from on_connect then let it fly!
|
|
// Seriously though, this way it is obvious to the user that something bad happened
|
|
// since they probably won't have the dlib logger enabled.
|
|
if (!my_fault)
|
|
throw;
|
|
}
|
|
}
|
|
|
|
uint64 next_id;
|
|
id_map con_map;
|
|
const static logger _dLog;
|
|
mutex m;
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
#ifdef NO_MAKEFILE
|
|
#include "server_iostream.cpp"
|
|
#endif
|
|
|
|
#endif // DLIB_SERVER_IOSTREAm_1_
|
|
|
|
|
|
|