e1c15e4924106d231ab1813bc6cc49747dc4d81f
[citadel.git] / citadel / housekeeping.c
1 /*
2  * This file contains housekeeping tasks which periodically
3  * need to be executed.
4  *
5  */
6
7 #include <stdlib.h>
8 #include <unistd.h>
9 #include <stdio.h>
10 #include <time.h>
11 #include <ctype.h>
12 #include <string.h>
13 #include <errno.h>
14 #include <pthread.h>
15 #include "citadel.h"
16 #include "server.h"
17 #include "proto.h"
18
19 /*
20  * Terminate idle sessions.  This function pounds through the session table
21  * comparing the current time to each session's time-of-last-command.  If an
22  * idle session is found it is terminated, then the search restarts at the
23  * beginning because the pointer to our place in the list becomes invalid.
24  */
25 void terminate_idle_sessions(void) {
26         struct CitContext *ccptr;
27         time_t now;
28         
29         time(&now);
30         for (ccptr = ContextList; ccptr != NULL; ccptr = ccptr->next) {
31                 if (  (ccptr!=CC)
32                    && (config.c_sleeping > 0)
33                    && (now - (ccptr->lastcmd) > config.c_sleeping) ) {
34                         lprintf(3, "Session %d timed out\n", ccptr->cs_pid);
35                         kill_session(ccptr->cs_pid);
36                         ccptr = ContextList;
37                         }
38                 }
39         }
40
41
42 /*
43  * Main housekeeping function.  This gets run whenever a session terminates.
44  */
45 void do_housekeeping() {
46
47         begin_critical_section(S_HOUSEKEEPING);
48         /*
49          * Terminate idle sessions.
50          */
51         lprintf(7, "Calling terminate_idle_sessions()\n");
52         terminate_idle_sessions();
53
54         /*
55          * If the server is scheduled to shut down the next time all
56          * users are logged out, now's the time to do it.
57          */
58         if ((ScheduledShutdown == 1) && (ContextList == NULL)) {
59                 lprintf(3, "Scheduled shutdown initiating.\n");
60                 master_cleanup();
61                 }
62         end_critical_section(S_HOUSEKEEPING);
63         }
64
65
66
67 /*
68  * Check (and fix) floor reference counts.  This doesn't need to be done
69  * very often, since the counts should remain correct during normal operation.
70  */
71 void check_ref_counts() {
72         int ref[MAXFLOORS];
73         struct quickroom qrbuf;
74         struct floor flbuf;
75         int a;
76
77         for (a=0; a<MAXFLOORS; ++a) ref[a] = 0;
78                 
79         for (a=0; a<MAXROOMS; ++a) {
80                 getroom(&qrbuf, a);
81                 if (qrbuf.QRflags & QR_INUSE) {
82                         ++ref[(int)qrbuf.QRfloor];
83                         }
84                 }
85
86         for (a=0; a<MAXFLOORS; ++a) {
87                 lgetfloor(&flbuf, a);
88                 flbuf.f_ref_count = ref[a];
89                 if (ref[a] > 0) flbuf.f_flags = flbuf.f_flags | QR_INUSE ;
90                 lputfloor(&flbuf, a);
91                 }
92         }       
93