Blame view

src/server.cpp 2.27 KB
Imanol-Mikel Barba Sabariego authored
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);
}