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