first commit
This commit is contained in:
118
CS4210/cs4210/proj1/src/server/boss.c
Normal file
118
CS4210/cs4210/proj1/src/server/boss.c
Normal file
@@ -0,0 +1,118 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/queue.h"
|
||||
#include "common/threading.h"
|
||||
|
||||
#include "boss.h"
|
||||
#include "client.h"
|
||||
|
||||
/* The id of the listening socket. */
|
||||
static socket_t m_listening_socket = -1;
|
||||
|
||||
/* Child count */
|
||||
static int child_count = 0;
|
||||
|
||||
/* List of child threads. */
|
||||
static pthread_t* m_children = NULL;
|
||||
|
||||
/* The queue of client sockets. */
|
||||
static queue_t m_client_sockets;
|
||||
|
||||
int boss_initialize(port_t pnum, int thread_count)
|
||||
{
|
||||
int index = 0;
|
||||
int result = 0;
|
||||
|
||||
#ifdef WIN32
|
||||
/* Have to also initialize WinSock */
|
||||
WSADATA uselessData;
|
||||
result = WSAStartup(MAKEWORD(2, 2), &uselessData);
|
||||
if (result)
|
||||
{
|
||||
fprintf(stderr, "[BOSS] Could not initialize WinSock.\n");
|
||||
net_report_error();
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
child_count = thread_count;
|
||||
|
||||
/* Make a listening socket: */
|
||||
m_listening_socket = net_listen_on_port(pnum);
|
||||
if (IS_BAD_SOCKET(m_listening_socket))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Initialize the queue */
|
||||
queue_initialize(&m_client_sockets);
|
||||
|
||||
/* Spawn children threads. */
|
||||
m_children = (pthread_t*) calloc(thread_count, sizeof(pthread_t));
|
||||
if (!m_children)
|
||||
{
|
||||
fprintf(stderr, "[BOSS] Could not allocate memory.\n");
|
||||
net_report_error();
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (index = 0; index < thread_count; index++)
|
||||
{
|
||||
result = pthread_create(m_children + index, NULL,
|
||||
client_run, &m_client_sockets);
|
||||
if (result)
|
||||
{
|
||||
fprintf(stderr, "[BOSS] Could not create child thread.\n");
|
||||
net_report_error();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* boss_run(void* param)
|
||||
{
|
||||
/* Loop infinitely accepting connections: */
|
||||
while (1)
|
||||
{
|
||||
/* Accept connection */
|
||||
socket_t client_socket = -1;
|
||||
sockaddress_t caddr;
|
||||
socklen_t sizeof_caddr = sizeof(sockaddress_t);
|
||||
|
||||
DEBUG_PRINTF(("[BOSS] Waiting for a client connection...\n"));
|
||||
|
||||
client_socket = accept(m_listening_socket,
|
||||
(struct sockaddr*) &caddr, &sizeof_caddr);
|
||||
if (IS_BAD_SOCKET(client_socket))
|
||||
{
|
||||
fprintf(stderr,
|
||||
"[BOSS] Could not accept client on listening socket\n");
|
||||
net_report_error();
|
||||
continue;
|
||||
}
|
||||
|
||||
DEBUG_PRINTF(("[BOSS] Got client on port %d.\n", ntohs(caddr.sin_port)));
|
||||
|
||||
/* Enqueue socket to be picked up by a client thread. */
|
||||
queue_enqueue(&m_client_sockets, (void*) client_socket);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int boss_clean()
|
||||
{
|
||||
/* Kill children */
|
||||
int index;
|
||||
for (index = 0; index < child_count; index++)
|
||||
{
|
||||
pthread_kill(m_children[index], SIGINT);
|
||||
}
|
||||
|
||||
DEBUG_PRINTF(("[BOSS] Shutting down...\n\n"));
|
||||
return net_close_socket(m_listening_socket);
|
||||
}
|
||||
Reference in New Issue
Block a user