server.cpp
2.27 KB
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
/** @file
* \brief Fichero de implementación de la clase Server
* \author Imanol Barba Sabariego
* \date 13/06/2013
*
* En este fichero se implementan los métodos de la clase Server definidos en server.h
*/
#include "server.h"
using namespace std;
int Server::getNWorkers()
{
return nWorkers;
}
void Server::setNWorkers(int n)
{
nWorkers = n;
}
list<pthread_t*>* Server::getStartedThreads()
{
return &startedThreads;
}
list<pthread_t*>* Server::getStoppedThreads()
{
return &stoppedThreads;
}
void Server::freeRAM(list<pthread_t*> *threadList)
{
int count = 0;
for(list<pthread_t*>::iterator it = threadList->begin(); it != threadList->end(); it++)
{
if(*it != 0)
{
delete *it;
*it = 0;
}
count++;
}
threadList->clear();
cout << "TCP: " << count << " Threads freed" << endl;
}
void Server::requestExit()
{
cout << "TCP: Exiting!" << endl;
shutdownServer = true;
ss.Close();
}
void Server::startServer(string i, int p)
{
Socket ss;
string ip = i;
int port = p;
signal(SIGPIPE, SIG_IGN);
try
{
int optval = 1;
ss.Create();
setsockopt(ss.getSock(),SOL_SOCKET,SO_REUSEADDR,&optval,sizeof optval);
ss.Bind(ip,port);
}
catch(SocketException& e)
{
cout << e.description() << endl;
return;
}
pthread_mutex_t m_mutex;
pthread_mutex_init(&m_mutex,0);
pthread_cond_t condition;
pthread_cond_init(&condition,0);
ss.Listen(N);
while(!shutdownServer)
{
pthread_mutex_lock(&m_mutex);
while(nWorkers >= N)
{
cout << "TCP: Server sleeping" << endl;
pthread_cond_wait(&condition,&m_mutex);
}
freeRAM(&stoppedThreads);
pthread_mutex_unlock(&m_mutex);
Socket *cs = new Socket();
try
{
ss.Accept(*cs);
}
catch(SocketException& e)
{
break;
}
pthread_mutex_lock(&m_mutex);
thread_args *t_args = new thread_args;
pthread_t *thread = new pthread_t;
t_args->mutex = &m_mutex;
t_args->condition = &condition;
t_args->id = workerID++;
t_args->s = cs;
t_args->serv = this;
t_args->thread = thread;
startedThreads.push_back(thread);
cout << "TCP: Client connected" << endl;
nWorkers++;
pthread_create(thread,NULL,WorkerThread,(void *)t_args);
pthread_mutex_unlock(&m_mutex);
}
cout << "TCP: Running Threads:" << endl;
freeRAM(&startedThreads);
cout << "TCP: Stopped Threads:" << endl;
freeRAM(&stoppedThreads);
}