#include #include #include #include #include #include #include #include #include #ifdef M_CORE_GBA #include #endif #ifdef M_CORE_GB #include #endif #include #include #include #include #include #include char *ms_last_error = ""; #define MAX_NUMBER_OF_THREADS 100 pthread_t pthread_client_connections[MAX_NUMBER_OF_THREADS]; pthread_cond_t cond_client_number_decreased; pthread_mutex_t mutex_number_connections; size_t connected_clients = 0; size_t number_of_threads = 0; void *handleClientConnection(void *user_data) { struct msClientConnectionData *data = (struct msClientConnectionData *) user_data; int client_fd = data->clientFd; size_t number_of_thread = data->numberOfThread; struct msPacket *packet = NULL; printf("Connection from client with id %lu and fd %d\n", number_of_thread, client_fd); while ((packet = msPacketRead(client_fd)) != NULL) { bool success = msPacketHandle(packet, client_fd, data); msPacketDestroy(&packet); if (!success) { fprintf(stderr, "Failed handling packet for client_fd %d, closing connection\n", client_fd); break; } } msClientConnectionDataDestroy(&data); if (close (client_fd) == 1) { fprintf(stderr, "Error closing socket %d\n", client_fd); } printf("Closing connection with id %lu and fd %d\n", number_of_thread, client_fd); pthread_mutex_lock(&mutex_number_connections); connected_clients--; pthread_mutex_unlock(&mutex_number_connections); pthread_cond_signal(&cond_client_number_decreased); return NULL; } #define SOCKET_ADDRESS "msgba.sock" #define BACKLOG 5 int main(int argc, char **argv) { struct sockaddr_un address; memset (&address, 0, sizeof address); address.sun_family = AF_UNIX; unlink(SOCKET_ADDRESS); size_t max_size_sun_path = sizeof address.sun_path - 1; if (strlen(SOCKET_ADDRESS) > max_size_sun_path) { fprintf(stderr, "Too big socket address"); exit (2); } strncpy(address.sun_path, SOCKET_ADDRESS, max_size_sun_path); int fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd == -1) { fprintf (stderr, "Unable to create socket\n"); exit (1); } if (bind (fd, (struct sockaddr *)&address, strlen (SOCKET_ADDRESS) + sizeof (address.sun_family)) == -1) { fprintf(stderr, "Unable to bind socket\n"); exit (1); } if (listen (fd, BACKLOG) == -1) { fprintf(stderr, "Unable to listen in socket\n"); exit (1); } pthread_cond_init(&cond_client_number_decreased, NULL); pthread_mutex_init(&mutex_number_connections, NULL); while (1) { int client_fd = accept(fd, NULL, NULL); pthread_attr_t attributes; pthread_attr_init(&attributes); pthread_attr_setdetachstate(&attributes, 1); pthread_mutex_lock(&mutex_number_connections); while (connected_clients == MAX_NUMBER_OF_THREADS) { pthread_cond_wait(&cond_client_number_decreased, &mutex_number_connections); } struct msClientConnectionData *data = msClientConnectionDataNew(number_of_threads, client_fd); pthread_create(&pthread_client_connections[connected_clients++], &attributes, &handleClientConnection, (void *)data); pthread_mutex_unlock(&mutex_number_connections); } }