8
#include "app_config.h"
9
#include "args_parser.h"
10
#include "client_info.h"
11
#include "client_manager.h"
12
#include "net/poll_table.h"
13
#include "net/socket_stream.h"
14
#include "jpeg2000/file_manager.h"
15
#include "jpeg2000/index_manager.h"
20
using namespace jpeg2000;
23
#define SERVER_NAME "ESA JPIP Server"
24
#define SERVER_APP_NAME "esa_jpip_server"
25
#define CONFIG_FILE "server.cfg"
33
bool child_lost = false;
34
IndexManager index_manager;
35
UnixAddress child_address("/tmp/child_unix_address");
36
UnixAddress father_address("/tmp/father_unix_address");
40
void *ClientThread(void *arg);
41
bool ParseArguments(int argc, char **argv);
44
void SIGCHLD_handler(int signal)
51
int main(int argc, char **argv)
55
InetAddress from_addr;
56
InetAddress listen_addr;
57
Socket listen_socket, new_conn;
60
return CERR("The shared information can not be set");
62
if (!cfg.Load(CONFIG_FILE))
63
return CERR("The configuration file can not be read");
65
if(!ArgsParser(cfg, app_info).Parse(argc, argv))
68
if(app_info.is_running())
69
return CERR("The server is already running");
71
if(!index_manager.Init(cfg.images_folder(), cfg.caching_folder()))
72
return CERR("The index manager can not be initialized");
74
app_info->father_pid = getpid();
76
cout << endl << SERVER_NAME << " " << VERSION << endl;
77
cout << endl << cfg << endl;
79
if (cfg.logging()) TraceSystem::AppendToFile(cfg.logging_folder() + SERVER_APP_NAME);
81
if (!File::Exists(cfg.caching_folder().c_str()))
82
ERROR("The cache folder does not exist");
84
if(cfg.address().size() <= 0) listen_addr = InetAddress(cfg.port());
85
else listen_addr = InetAddress(cfg.address().c_str(), cfg.port());
87
if (!listen_socket.OpenInet())
88
ERROR("The server listen socket can not be created");
89
else if (!listen_socket.ListenAt(listen_addr))
90
ERROR("The server listen socket can not be initialized");
93
LOG(SERVER_NAME << " started");
95
signal(SIGCHLD, SIG_IGN);
97
poll_table.Add(listen_socket, POLLIN);
99
if(!father_socket.OpenUnix(SOCK_DGRAM)) {
100
ERROR("The father unix socket can not be created");
104
if(!father_socket.BindTo(father_address.Reset())) {
105
ERROR("The father unix socket can not be bound");
109
poll_table.Add(father_socket, POLLIN);
113
if (!fork()) return ChildProcess();
116
signal(SIGCHLD, SIGCHLD_handler);
120
res = poll_table.Poll();
130
if (poll_table[0].revents & POLLIN)
132
new_conn = listen_socket.Accept(&from_addr);
134
if (!new_conn.IsValid()) ERROR("Problems accepting a new connection");
137
if(app_info->num_connections >= cfg.max_connections()) {
138
LOG("Refusing a connection because the limit has been reached");
142
LOG("New connection from " << from_addr.GetPath() << ":" << from_addr.GetPort() << " [" << (int)new_conn << "]");
144
if(!father_socket.SendDescriptor(child_address, new_conn, new_conn)) {
145
ERROR("The new socket can not be sent to the child process");
149
poll_table.Add(new_conn, POLLRDHUP | POLLERR | POLLHUP | POLLNVAL);
150
app_info->num_connections++;
156
if(poll_table[1].revents & POLLIN)
158
father_socket.Receive(&fd, sizeof(int));
159
LOG("Closing the connection [" << fd << "] from child");
160
app_info->num_connections--;
161
poll_table.Remove(fd);
165
for(int i = 2; i < poll_table.GetSize(); i++)
167
if (poll_table[i].revents)
169
LOG("Closing the connection [" << poll_table[i].fd << "]");
170
app_info->num_connections--;
171
close(poll_table[i].fd);
172
poll_table.RemoveAt(i);
176
if(app_info->num_connections < 0)
177
app_info->num_connections = 0;
183
listen_socket.Close();
191
int sock, father_sock;
192
pthread_t service_tid;
193
ClientInfo *client_info;
195
app_info->child_iterations++;
196
app_info->child_pid = getpid();
198
signal(SIGPIPE, SIG_IGN);
200
LOG("Child process created (PID = " << getpid() << ")");
202
if(!child_socket.OpenUnix(SOCK_DGRAM)) {
203
ERROR("The child unix socket can not be created");
207
if(!child_socket.BindTo(child_address.Reset())) {
208
ERROR("The child unix socket can not be bound");
212
for (int i = 2; i < poll_table.GetSize(); i++)
214
sock = poll_table[i].fd;
215
client_info = new ClientInfo(0, sock, sock);
217
LOG("Creating a client thread for the old connection [" << sock << "]");
219
if (pthread_create(&service_tid, NULL, ClientThread, client_info) == -1)
221
ERROR("A new client thread for the old connection [" << sock << "] can not be created");
226
pthread_detach(service_tid);
231
child_socket.ReceiveDescriptor(&sock, &father_sock);
232
client_info = new ClientInfo(base_id++, sock, father_sock);
234
LOG("Creating a client thread for the new connection [" << sock << "|" << father_sock << "]");
236
if (pthread_create(&service_tid, NULL, ClientThread, client_info) == -1)
238
LOG("A new client thread for the new connection [" << sock << "|" << father_sock << "] can not be created");
243
pthread_detach(service_tid);
250
void *ClientThread(void *arg)
253
ClientInfo *client_info = (ClientInfo *)arg;
256
ClientManager(cfg, app_info, index_manager).Run(client_info);
258
ClientManager(cfg, app_info, index_manager).RunBasic(client_info);
261
sock = client_info->father_sock();
262
res = child_socket.SendTo(father_address, &sock, sizeof(int));
264
if(res < (int)sizeof(int))
265
ERROR("The connection [" << sock << "] could not be closed");