aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriceyrazor <iceyrazor@mailfence.com>2026-10-11 00:21:32 -0500
committericeyrazor <iceyrazor@mailfence.com>2026-10-11 00:21:32 -0500
commita926ae205ecb42a603e428346cf99dc1e66ed691 (patch)
tree9d207cf8f84dc1d9e48b541f0a18309f7f96c442
parent3521cc6e1a87f16c8db5c3c5a0c3cf59e1ff04cb (diff)
major refactor: Some Thread Safety
- removed web. silly to have that in a socket library - made shared changing variables atomic - added mutex locking to some things - removed requirement for iceys-c-libs (that was a web thing) - removed launch variable - check if on_message is actually defined - init on_message and on_disconnect NULL
-rw-r--r--README.md4
-rwxr-xr-xServer.c6
-rwxr-xr-xServer.h18
-rwxr-xr-xlaunch-socket.c279
-rwxr-xr-xlaunch-socket.h6
-rwxr-xr-xlaunch-web.c101
-rwxr-xr-xlaunch-web.h15
7 files changed, 167 insertions, 262 deletions
diff --git a/README.md b/README.md
index e25d25b..b1696a7 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,3 @@
# socket
-my small websocket and webserver libs.
-
-requires iceys-c-libs a5e1191ad6c34636eb49c0ddaeb9af1bd5c07a2d
+my small socket library.
diff --git a/Server.c b/Server.c
index 3fb55c6..8c3c8c4 100755
--- a/Server.c
+++ b/Server.c
@@ -4,7 +4,7 @@
#include <stdlib.h>
#include <Server.h>
-struct Server server_constructor(int domain, int service, int protocol, ulong interface, int port, int backlog, pthread_t(*launch)(struct Server *server)){
+struct Server server_constructor(int domain, int service, int protocol, ulong interface, int port, int backlog){
struct Server server;
server.domain=domain;
@@ -37,7 +37,9 @@ struct Server server_constructor(int domain, int service, int protocol, ulong in
server.accepted_socket=NULL;
- server.launch=launch;
+ server.on_message=NULL;
+ server.on_disconnect=NULL;
+
server.running=true;
return server;
diff --git a/Server.h b/Server.h
index 0a55543..241351a 100755
--- a/Server.h
+++ b/Server.h
@@ -5,6 +5,7 @@
#include <netinet/in.h>
#include <stdbool.h>
#include <pthread.h>
+#include <stdatomic.h>
struct AcceptedSocket{
int socketFD;
@@ -12,7 +13,7 @@ struct AcceptedSocket{
int error;
bool succ;
pthread_t thread_id;
- bool shutdown;
+ atomic_bool shutdown;
struct AcceptedSocket *next;
};
@@ -24,25 +25,22 @@ struct Server{
u_long interface;
int port;
int backlog;
- bool running;
+ atomic_bool running;
+
+ pthread_t server_thread_id;
+ pthread_t cleanup_thread_id;
struct sockaddr_in address;
int socket;
- char *html_folder;
+ pthread_mutex_t list_lock;
struct AcceptedSocket *accepted_socket;
- pthread_t (*launch)(struct Server *server);
void (*on_message)(struct Server *server, char message[], ssize_t amountRecv, int socketFD);
void (*on_disconnect)(struct Server *server, int socketFD);
};
-/*
- * AF_INET, SOCK_STREAM, 0, INADDR_ANY, port, 10, launch_socket
- * or
- * AF_INET, SOCK_STREAM, 0, INADDR_ANY, port, 10, launch
- */
-struct Server server_constructor(int domain, int service, int protocol, u_long interface, int port, int backlog, pthread_t (*launch)(struct Server *server));
+struct Server server_constructor(int domain, int service, int protocol, u_long interface, int port, int backlog);
#endif /* Server_h */
diff --git a/launch-socket.c b/launch-socket.c
index 0c2881c..38cd4eb 100755
--- a/launch-socket.c
+++ b/launch-socket.c
@@ -1,188 +1,209 @@
-#include <stdlib.h>
-#include <unistd.h>
+#include <Server.h>
#include <bits/pthreadtypes.h>
-#include <pthread.h>
#include <netinet/in.h>
-#include <stdio.h>
-#include <Server.h>
-#include <sys/socket.h>
#include <poll.h>
+#include <pthread.h>
+#include <stdatomic.h>
#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <launch-socket.h>
-struct AcceptedSocket* acceptIncoming(struct Server *server){
- int serverSocketFd=server->socket;
-
- struct sockaddr_in clientAddress;
- socklen_t ClientAddressSize = sizeof(struct sockaddr);
- int clientSocketFD = accept(serverSocketFd,(struct sockaddr *)&clientAddress,&ClientAddressSize);
-
- if(server->running){
- struct AcceptedSocket* acceptedSocket = malloc(sizeof(struct AcceptedSocket));
- acceptedSocket->address=clientAddress;
- acceptedSocket->socketFD=clientSocketFD;
- acceptedSocket->succ=clientSocketFD>0;
- acceptedSocket->next=NULL;
- acceptedSocket->shutdown=false;
-
- if(!acceptedSocket){
- acceptedSocket->error=clientSocketFD;
- } else {
- if(server->running){
- struct AcceptedSocket *sel_socket=server->accepted_socket;
-
- if(sel_socket==NULL){
- server->accepted_socket=acceptedSocket;
- } else {
- while(1){
- if(sel_socket->next==NULL){
- sel_socket->next=acceptedSocket;
- break;
- } else {
- sel_socket=sel_socket->next;
- }
- }
- }
- }
- }
- return acceptedSocket;
- } else {
- return NULL;
- }
-}
-
-struct recv_data_arg{
+struct recv_data_arg {
int socketFD;
- struct Server *server;
- struct AcceptedSocket *curr_socket;
+ struct Server* server;
+ struct AcceptedSocket* curr_socket;
};
-void *recv_data(void *threadarg){
- struct recv_data_arg *recv_d_arg;
- recv_d_arg=(struct recv_data_arg *) threadarg;
+void* recv_data(void* threadarg)
+{
+ struct recv_data_arg* recv_d_arg;
+ recv_d_arg = (struct recv_data_arg*)threadarg;
- while(recv_d_arg->server->running){
- char buffer[30000]={0};
- ssize_t amountRecv=recv(recv_d_arg->socketFD, buffer, 30000, 0);
+ while (recv_d_arg->server->running) {
+ char buffer[30000] = { 0 };
+ ssize_t amountRecv = recv(recv_d_arg->socketFD, buffer, 30000, 0);
- if(recv_d_arg->server->running){
- if(amountRecv==0) break;
+ if (recv_d_arg->server->running && recv_d_arg->curr_socket->shutdown == false) {
+ if (amountRecv == 0)
+ break;
- recv_d_arg->server->on_message(recv_d_arg->server, buffer, amountRecv, recv_d_arg->socketFD);
+ if (recv_d_arg->server->on_message)
+ recv_d_arg->server->on_message(recv_d_arg->server, buffer, amountRecv, recv_d_arg->socketFD);
}
}
-
-
- recv_d_arg->curr_socket->shutdown=true;
+ recv_d_arg->curr_socket->shutdown = true;
close(recv_d_arg->socketFD);
- if(recv_d_arg->server->on_disconnect){
- recv_d_arg->server->on_disconnect(recv_d_arg->server,recv_d_arg->socketFD);
- }
- free(recv_d_arg);
+ if (recv_d_arg->server->on_disconnect)
+ recv_d_arg->server->on_disconnect(recv_d_arg->server, recv_d_arg->socketFD);
+ free(recv_d_arg);
pthread_exit(NULL);
}
-void cleanup_conns(struct Server *server){
- if(server->accepted_socket){
- struct AcceptedSocket *sel_socket=server->accepted_socket;
- struct AcceptedSocket *prev_socket=server->accepted_socket;
- struct AcceptedSocket *prev2_socket=server->accepted_socket;
- while (sel_socket!=NULL){
- sel_socket=sel_socket->next;
- if(prev_socket->shutdown==true){
- if(prev_socket==server->accepted_socket){
+void cleanup_conns(struct Server* server)
+{
+ pthread_mutex_lock(&server->list_lock);
+ if (server->accepted_socket) {
+ struct AcceptedSocket* sel_socket = server->accepted_socket;
+ struct AcceptedSocket* prev_socket = server->accepted_socket;
+ struct AcceptedSocket* prev2_socket = server->accepted_socket;
+
+ while (sel_socket != NULL) {
+ sel_socket = sel_socket->next;
+ if (prev_socket->shutdown == true) {
+ if (prev_socket == server->accepted_socket) {
+ pthread_join(server->accepted_socket->thread_id,NULL);
free(server->accepted_socket);
- server->accepted_socket=sel_socket;
+ server->accepted_socket = sel_socket;
} else {
+ pthread_join(prev2_socket->next->thread_id,NULL);
free(prev2_socket->next);
- prev2_socket->next=sel_socket;
+ prev2_socket->next = sel_socket;
}
} else {
- prev2_socket=prev_socket;
+ prev2_socket = prev_socket;
}
- prev_socket=sel_socket;
+ prev_socket = sel_socket;
}
}
+ pthread_mutex_unlock(&server->list_lock);
}
-void *await_client(void *threadarg){
- struct Server *server;
- server=(struct Server *) threadarg;
- while (server->running){
- printf("\n=== WAITING FOR CONNECTION ===\n\n");
-
- struct AcceptedSocket* new_socket = acceptIncoming(server);
- if(server->running){
- if(new_socket->succ==0){ free(new_socket); } else {
+void* cleanup_loop(void* threadarg)
+{
+ struct Server* server;
+ server = (struct Server*)threadarg;
+ while (server->running) {
+ cleanup_conns(server);
+ for (int i = 0; i < 60 && server->running; i++) {
+ sleep(1);
+ }
+ }
+
+ pthread_exit(NULL);
+}
+
+struct AcceptedSocket* acceptIncoming(struct Server* server)
+{
+ int serverSocketFd = server->socket;
+
+ struct sockaddr_in clientAddress;
+ socklen_t ClientAddressSize = sizeof(struct sockaddr);
+ int clientSocketFD = accept(serverSocketFd, (struct sockaddr*)&clientAddress, &ClientAddressSize);
- struct recv_data_arg *recv_d_arg;
- recv_d_arg=malloc(sizeof(* recv_d_arg));
- recv_d_arg->socketFD=new_socket->socketFD;
- recv_d_arg->server=server;
- recv_d_arg->curr_socket=new_socket;
+ if (server->running) {
+ struct AcceptedSocket* acceptedSocket = malloc(sizeof(struct AcceptedSocket));
+ acceptedSocket->address = clientAddress;
+ acceptedSocket->socketFD = clientSocketFD;
+ acceptedSocket->succ = clientSocketFD > 0;
+ acceptedSocket->next = NULL;
+ acceptedSocket->shutdown = false;
+
+ if (!acceptedSocket) {
+ acceptedSocket->error = clientSocketFD;
+ } else {
+ if (server->running) {
+ struct AcceptedSocket* sel_socket = server->accepted_socket;
- int thread_err=pthread_create(&new_socket->thread_id, NULL, recv_data, recv_d_arg);
+ if (sel_socket == NULL) {
+ server->accepted_socket = acceptedSocket;
+ } else {
+ while (1) {
+ if (sel_socket->next == NULL) {
+ sel_socket->next = acceptedSocket;
+ break;
+ } else {
+ sel_socket = sel_socket->next;
+ }
+ }
+ }
}
}
+ return acceptedSocket;
+ } else {
+ return NULL;
}
-
- pthread_exit(NULL);
}
-void *cleanup_loop(void *threadarg){
- struct Server *server;
- server=(struct Server *) threadarg;
- while(server->running){
- cleanup_conns(server);
- sleep(60);
+void* await_client(void* threadarg)
+{
+ struct Server* server;
+ server = (struct Server*)threadarg;
+ while (server->running) {
+ struct AcceptedSocket* new_socket = acceptIncoming(server);
+ if (server->running) {
+ if (new_socket->succ == 0) {
+ free(new_socket);
+ } else {
+
+ struct recv_data_arg* recv_d_arg = malloc(sizeof(*recv_d_arg));
+ recv_d_arg->socketFD = new_socket->socketFD;
+ recv_d_arg->server = server;
+ recv_d_arg->curr_socket = new_socket;
+
+ int thread_err = pthread_create(&new_socket->thread_id, NULL, recv_data, recv_d_arg);
+ if (thread_err != 0) {
+ fprintf(stderr, "ERROR CREATING THREAD FOR CLIENT: %d\n", thread_err);
+ perror("await client error");
+ exit(-1);
+ }
+ }
+ }
}
pthread_exit(NULL);
}
-void server_close_socket(struct Server *server){
- server->running=false;
+int server_close_socket(struct Server* server)
+{
+ server->running = false;
+ pthread_join(server->cleanup_thread_id, NULL);
- struct AcceptedSocket *sel_socket_A=server->accepted_socket;
- while(sel_socket_A!=NULL){
- close(sel_socket_A->socketFD);
- sel_socket_A->shutdown=true;
- sel_socket_A=sel_socket_A->next;
- }
+ int shuterr = shutdown(server->socket, SHUT_RDWR);
+ pthread_join(server->server_thread_id, NULL);
+ int closeerr = close(server->socket);
- int shuterr=shutdown(server->socket,SHUT_RDWR);
- int closeerr=close(server->socket);
-
- sleep(2);
cleanup_conns(server);
-
- printf("\nshutdown with %d : %d\n",shuterr,closeerr);
+ pthread_mutex_destroy(&server->list_lock);
+ return shuterr+closeerr;
}
-pthread_t launch_socket(struct Server *server){
- int addrlen= sizeof(server->address);
+int launch_socket(struct Server* server)
+{
+ pthread_mutex_init(&server->list_lock, NULL);
- printf("running on port: %d\n",server->port);
-
- pthread_t id2;
- int thread_err2=pthread_create(&id2, NULL, cleanup_loop, (void *) server);
- if (thread_err2!=0){
- fprintf(stderr,"ERROR WITH CLEANUP LOOP: %d\n",thread_err2);
+ int thread_err2 = pthread_create(&server->cleanup_thread_id, NULL, cleanup_loop, (void*)server);
+ if (thread_err2 != 0) {
+ fprintf(stderr, "ERROR WITH CLEANUP LOOP: %d\n", thread_err2);
perror("cleanup loop err");
exit(-1);
}
- pthread_t id;
- int thread_err=pthread_create(&id, NULL, await_client, (void *) server);
- if (thread_err!=0){
- fprintf(stderr,"ERROR WITH AWAIT CLIENT: %d\n",thread_err);
+ int thread_err = pthread_create(&server->server_thread_id, NULL, await_client, (void*)server);
+ if (thread_err != 0) {
+ fprintf(stderr, "ERROR WITH AWAIT CLIENT: %d\n", thread_err);
perror("await client error");
exit(-1);
}
- return id;
+ return 0;
+}
+
+void broadcast(struct Server* server, int socketFD, char* message){
+ pthread_mutex_lock(&server->list_lock);
+ struct AcceptedSocket* sel_socket = server->accepted_socket;
+ while (sel_socket != NULL) {
+ if (sel_socket->shutdown == false && sel_socket->socketFD != socketFD) {
+ send(sel_socket->socketFD, message, 30000, 0);
+ }
+ sel_socket = sel_socket->next;
+ }
+ pthread_mutex_unlock(&server->list_lock);
} \ No newline at end of file
diff --git a/launch-socket.h b/launch-socket.h
index 0f87b5d..2e10b04 100755
--- a/launch-socket.h
+++ b/launch-socket.h
@@ -11,7 +11,9 @@
#include <string.h>
#include <Server.h>
-void server_close_socket(struct Server *server);
+int server_close_socket(struct Server *server);
-pthread_t launch_socket(struct Server *server);
+int launch_socket(struct Server *server);
+
+void broadcast(struct Server *server, int socketFD, char* message);
#endif
diff --git a/launch-web.c b/launch-web.c
deleted file mode 100755
index ff2970b..0000000
--- a/launch-web.c
+++ /dev/null
@@ -1,101 +0,0 @@
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <pthread.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <iceys-utils.h>
-#include <Server.h>
-
-void server_close(struct Server *server){
- server->running=false;
-
- sleep(1);
-
- int shuterr=shutdown(server->socket,SHUT_RDWR);
- int closeerr=close(server->socket);
-
- printf("\nshutdown with %d : %d\n",shuterr,closeerr);
- //free(server);
-}
-
-void *server_loop(void *threadarg){
- struct Server *server;
- server=(struct Server *) threadarg;
-
- char buffer[30000]={0};
- int addrlen= sizeof(server->address);
-
- int new_socket;
- char *meta_type="\r\ncontent-type: text/html\r\n\r\n";
-
- printf("running on port: %d",server->port);
-
- while (server->running){
- char metadata[100]="";
-
- printf("\n=== WAITING FOR CONNECTION ===\n\n");
- new_socket = accept(server->socket, (struct sockaddr *)&server->address, (socklen_t *)&addrlen);
-
- if(new_socket<0){ break; }
-
- if(read(new_socket,buffer,29999)<0){ printf("\nREAD FAILED\n\n"); close(new_socket); break; }
- buffer[29999]='\0';
-
- printf("%s\n",buffer);
-
- char response[30000] = {0};
-
-
- char file_req_buf[1000]={0};
- strcpy(file_req_buf,server->html_folder);
- char file_req[1000]={0};
- str_before_nth(buffer+5, file_req, ' ', 0);
- strcat(file_req_buf,file_req);
-
-
- printf("file req: %s====\n",file_req_buf);
-
-
- if(strncmp(file_req, "", 1) == 0){
- strcat(file_req_buf,"index.html");
- }
-
- char file_req_buf2[1000]={0};
- strcpy(file_req_buf2,str_remove_all(file_req_buf,".."));
- printf("file ret: %s====\n",file_req_buf);
-
-
- if (access(file_req_buf, F_OK) == 0) {
- char *status="HTTP/1.0 200 OK";
- memcpy(metadata,status,strlen(status));
- memcpy(metadata+strlen(metadata),meta_type,strlen(meta_type));
- memcpy(response, metadata, strlen(metadata));
- FILE* file=fopen(file_req_buf, "r");
- fread(response + strlen(metadata), 30000 - strlen(metadata) - 1, 1, file);
- fclose(file);
- } else {
- char *status="HTTP/1.0 404 Not Found";
- memcpy(metadata,status,strlen(status));
- memcpy(metadata+strlen(metadata),meta_type,strlen(meta_type));
- memcpy(response, metadata, strlen(metadata));
- char* error = "error 404 file not found";
- memcpy(response + strlen(metadata), error, strlen(error));
- }
-
- printf("\n\n==response==\n%s\n",response);
-
- write(new_socket, response, strlen(response));
- close(new_socket);
- }
-
- pthread_exit(NULL);
-}
-
-pthread_t launch(struct Server *server){
- //HTTP/1.0 200 OK
-
- pthread_t id;
- int thread_err=pthread_create(&id, NULL, server_loop, (void *) server);
- return id;
-}
diff --git a/launch-web.h b/launch-web.h
deleted file mode 100755
index 0a25288..0000000
--- a/launch-web.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef launch_web_h
-#define launch_web_h
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <pthread.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <Server.h>
-#include <iceys-utils.h>
-
-void server_close(struct Server *server);
-
-pthread_t launch(struct Server *server);
-#endif