File: sockpool.h

package info (click to toggle)
nget 0.27.1-1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 3,152 kB
  • ctags: 2,941
  • sloc: cpp: 15,311; python: 4,075; makefile: 242; ansic: 239; sh: 184
file content (127 lines) | stat: -rw-r--r-- 3,332 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
/*
    sockpool.* - socket connection pool
    Copyright (C) 1999-2002  Matthew Mueller <donut AT dakotacom.net>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#ifndef __SOCKPOOL_H__
#define __SOCKPOOL_H__

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdarg.h>
#include "server.h"
#include "file.h"
#include "log.h"

class Connection {
	protected:
		time_t lastuse;
	public:
		c_file_tcp sock;
		c_server::ptr server;
		c_group_info::ptr curgroup;
		bool freshconnect;
		bool server_ok;


		int putline(int echo,const char * str,...)
			__attribute__ ((format (printf, 3, 4)));
		int doputline(int echo,const char * str,va_list ap);
		int getline(int echo);

		
		time_t age(void) const {
			return time(NULL)-lastuse;
		}
		void touch(void) {
			lastuse=time(NULL);
		}
		bool isopen(void) const {
			return sock.isopen();
		}
		void close(int fast=0) {
			if (sock.isopen()){
				if (!fast)
					putline(quiet<2,"QUIT");
				else if (quiet<2)
					printf("%s close(fast)\n", server->shortname.c_str());
				sock.close();
			}
		}
		Connection(c_server::ptr serv):lastuse(0), sock(serv->addr.c_str(), "nntp"), server(serv){
			sock.initrbuf();
			freshconnect=true;
			server_ok=false;
			curgroup=NULL;
		}
};


typedef map<c_server::ptr, Connection *> t_connection_map;

class SockPool {
	protected:
		//t_connection_map used_connections;
		t_connection_map connections;

		void connection_erase(t_connection_map::iterator i);
	public:
		
		bool is_connected(const c_server::ptr &server) const {
			return (connections.find(server) != connections.end());
		}

//		int total_connections(void) const {
//			return free_connections.size() + used_connections.size();
//		}

		Connection* connect(const c_server::ptr &server);
		void release(Connection *connection);
		void expire_old_connection(void);
		void expire_connections(bool closeall=false);

		~SockPool() {
			expire_connections(true);
		}
};


class ConnectionHolder {
	protected:
		SockPool * pool;
		Connection ** connection;
	public:
		ConnectionHolder(SockPool *sockpool, Connection **conn, const c_server::ptr &server):pool(sockpool), connection(conn) {
			PDEBUG(DEBUG_MED, "aquiring connection to %s", server->alias.c_str());
			*connection = pool->connect(server);
			PDEBUG(DEBUG_MED, "aquired connection to %s (%p)", server->alias.c_str(), *connection);
			pool->expire_connections();
		}
		~ConnectionHolder() {
			PDEBUG(DEBUG_MED, "releasing connection to (%p)", *connection);
			assert(pool);
			assert(connection);
			if (*connection) { //*connection can be NULL if pool->connect failed.
				pool->release(*connection);
				*connection=NULL;
			}
		}
};

#endif