File: server_iostream_1.h

package info (click to toggle)
mldemos 0.5.1-3
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 32,224 kB
  • ctags: 46,525
  • sloc: cpp: 306,887; ansic: 167,718; ml: 126; sh: 109; makefile: 2
file content (164 lines) | stat: -rw-r--r-- 4,461 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// 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"


namespace dlib
{

    template <
        typename server_base,
        typename ssbuf,
        typename id_map
        >
    class server_iostream_1 : public server_base 
    {

        /*!
            REQUIREMENTS ON ssbuf
                - must be an implementation of dlib/sockstreambuf/sockstreambuf_kernel_abstract.h

            REQUIREMENTS ON id_map
                - must be an implementation of dlib/map/map_kernel_abstract.h and domain must
                  be set to uint64 and range must be set to connection*

            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
        !*/

    public:
        server_iostream_1(
        ) :
            next_id(0)
        {}

        ~server_iostream_1(
        )
        {
            server_base::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
            {
                ssbuf 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;
        

    };

    template <
        typename server_base,
        typename ssbuf,
        typename id_map
        >
    const logger server_iostream_1<server_base,ssbuf,id_map>::dlog("dlib.server");

}

#endif // DLIB_SERVER_IOSTREAm_1_