updated docs
[rlserver.git] / sessions.c
blob930e44a1badaffb9c843936abb73080f6a5822e5
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <signal.h>
5 #include <sys/socket.h>
6 #include <pthread.h>
7 #include "vt100.h"
8 #include "sessions.h"
12 session_info *sessionlist = NULL;
13 int session_count = 0;
14 pthread_mutex_t sessionlist_mutex = PTHREAD_MUTEX_INITIALIZER;
18 session_info* add_session (int sock)
20 session_info *ps = (session_info*)malloc(sizeof(session_info));
21 if (ps == NULL) return NULL;
23 // fill data
24 ps->prev = NULL;
25 ps->next = NULL;
26 ps->child_pid = 0;
27 ps->socket = sock;
28 ps->user_id = -1;
29 ps->user_name[0] = 0;
30 ps->game[0] = 0;
31 ps->term = NULL;
32 ps->term_wid = 80;
33 ps->term_hgt = 24;
34 ps->pty_master = -1;
35 ps->observer_count = 0;
36 ps->observers = NULL;
37 pthread_mutex_init (&ps->mutex, NULL);
38 ps->last_activity = time(NULL);
41 pthread_mutex_lock (&sessionlist_mutex);
43 // add it to the list
44 if (sessionlist == NULL)
46 sessionlist = ps;
48 else
50 session_info *p = sessionlist;
51 while (p->next != NULL) p = p->next;
52 p->next = ps;
53 ps->prev = p;
55 session_count++;
57 pthread_mutex_unlock (&sessionlist_mutex);
59 return ps;
64 void remove_session (session_info *sess)
66 session_info *s;
68 pthread_mutex_lock (&sessionlist_mutex);
69 pthread_mutex_lock (&sess->mutex);
71 for (s = sessionlist; s != NULL; s = s->next)
73 // remove sess from the list
74 if (s == sess)
76 if (s->next) s->next->prev = s->prev;
77 if (s->prev) s->prev->next = s->next;
79 if (sessionlist == sess) sessionlist = sess->next;
80 session_count--;
82 // remove socket from observers
83 else
85 int i;
86 // no need to lock s->mutex because add_observer() is blocked by sessionlist_mutex
87 for (i = 0; i < s->observer_count; i++)
89 if (s->observers[i] == sess->socket)
91 s->observers[i--] = s->observers[s->observer_count--];
97 pthread_mutex_unlock (&sessionlist_mutex);
99 pthread_mutex_unlock (&sess->mutex);
100 pthread_mutex_destroy (&sess->mutex);
101 free (sess->term);
102 free (sess);
107 int user_is_connected (int id)
109 session_info *s;
111 pthread_mutex_lock (&sessionlist_mutex);
113 for (s = sessionlist; s != NULL; s = s->next)
115 if (s->user_id == id)
117 pthread_mutex_unlock (&sessionlist_mutex);
118 return 1;
122 pthread_mutex_unlock (&sessionlist_mutex);
123 return 0;
128 void stop_observing (session_info *sess)
130 session_info *s;
132 pthread_mutex_lock (&sessionlist_mutex);
134 for (s = sessionlist; s != NULL; s = s->next)
136 // remove socket from observers
137 int i;
138 // no need to lock s->mutex because add_observer() is blocked by sessionlist_mutex
139 for (i = 0; i < s->observer_count; i++)
141 if (s->observers[i] == sess->socket)
143 s->observers[i--] = s->observers[--s->observer_count];
148 pthread_mutex_unlock (&sessionlist_mutex);
153 int add_observer (int n, int sock)
155 session_info *s;
156 int i = 0, done = 0;
158 pthread_mutex_lock (&sessionlist_mutex);
160 for (s = sessionlist; s != NULL; s = s->next)
162 if (s->game[0] == 0 || s->observer_count == -1) continue;
163 if (i++ != n) continue;
165 pthread_mutex_lock (&s->mutex);
166 s->observers = (int*)realloc(s->observers, (s->observer_count + 1) * sizeof(int));
167 s->observers[s->observer_count++] = sock;
168 pthread_mutex_unlock (&s->mutex);
169 done = 1;
170 break;
173 if (s->term != NULL) term_copy_data (s->term, sock);
175 pthread_mutex_unlock (&sessionlist_mutex);
176 return done;
181 void close_sessions (void)
183 session_info *s;
184 for (s = sessionlist; s != NULL; s = s->next)
186 if (s->pty_master != -1) close (s->pty_master);
187 close (s->socket);
193 void release_sessions (void)
195 session_info *s;
196 for (s = sessionlist; s != NULL; s = s->next)
198 free (s->observers);
199 pthread_mutex_destroy (&s->mutex);
205 void terminate_games (void)
207 session_info *s;
210 pthread_mutex_lock (&sessionlist_mutex);
212 for (s = sessionlist; s != NULL; s = s->next)
214 if (!s->child_pid) continue;
215 kill (s->child_pid, SIGTERM);
218 pthread_mutex_unlock (&sessionlist_mutex);