File: timer.cc

package info (click to toggle)
trafstats 0.4.20-1
  • links: PTS
  • area: main
  • in suites: woody
  • size: 296 kB
  • ctags: 110
  • sloc: cpp: 1,036; sh: 475; perl: 173; makefile: 98
file content (147 lines) | stat: -rw-r--r-- 3,761 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
 * timer.cc: This file contains all the code for the timer thread,
 * which simply updates the timestamp when needed.
*/

#include "trafstats.h"


extern pthread_cond_t timer_gonogo;
extern pthread_mutex_t timelock;
extern pthread_mutex_t timergonogolock;

extern int verbosity;
extern bool run;
extern char* timestamp;
extern PgDatabase *dbconn;

void timerSigHandler(int sig) {
	if(verbosity >= LOG_DEBUG) {
		syslog(LOG_DEBUG,"[timer] Received signal %d",
				sig);
	}
	switch(sig) {
	case SIGUSR1: // Ended from main thread.
		// FALLTHRU
	case SIGINT: // ^C pressed or ended from the main thread
		// FALLTHRU
	case SIGTERM: // Killed from the command prompt.
		if(verbosity >= LOG_DEBUG) {
			syslog(LOG_DEBUG,"[timer] Received signal %d, exiting.",
					sig);
		}
		break;
	default:
		if(verbosity >= LOG_WARNING) {
			syslog(LOG_WARNING,"[timer] Received unaccounted for signal %d",sig);
		}
		break;
	}
}

void *timerThread(void *d) {
	timer_options *topts=(struct timer_options *)d;

	if(verbosity>=LOG_DEBUG) {
		syslog(LOG_DEBUG,"[timer] New timestamp every %d seconds, calling database using <%s>",
				topts->interval,
				topts->db_connstr);
	}

	// First try to connect to the database.
	// 
	// pthread_mutex_lock(&timergonogolock);
	if(verbosity>=LOG_DEBUG) {
		syslog(LOG_DEBUG,"[timer] Contacting database.");
	}

	PgDatabase* dbconn = new PgDatabase(topts->db_connstr);
	if(dbconn->ConnectionBad()) { // Failed connect.
		if(verbosity>=LOG_CRIT) {
			syslog(LOG_CRIT,"[timer]: Failed second connecion to database: %s",
					dbconn->ErrorMessage());
			if(verbosity>=LOG_DEBUG) {
				syslog(LOG_DEBUG,"[timer] Connection string was: <%s>",topts->db_connstr);
			}
		}
		run=0;
		pthread_cond_broadcast(&timer_gonogo);
	//	pthread_mutex_unlock(&timergonogolock);
		pthread_exit(NULL);
	} // Okay, it worked. 

	char *query;
	if((topts->interval % 3600) == 0) {
		query="SELECT DATE_TRUNC('hour',now())";
	} else {
		query="SELECT DATE_TRUNC('minute',now())";
	}

	if(verbosity>=LOG_DEBUG) {
		syslog(LOG_DEBUG,"[timer] Using query <%s>.",query);
	}
	
	timestamp=(char *) malloc(TS_TIMESTAMP_SIZE);
	int ok=dbconn->ExecCommandOk(query);
	if(verbosity>=LOG_DEBUG) {
			syslog(LOG_DEBUG,"[timer] Postgres result: %d", ok);
			syslog(LOG_DEBUG,"[timer] Postgres error: %s", dbconn->ErrorMessage());
	}

	/* Don't ask me why, but the above returns false even though the 
	 * query worked fine.
	 
	if(!ok) {
		if(verbosity >= LOG_ERR) {
			syslog(LOG_ERR,"[timer] Failed to get timestamp: %s",
				dbconn->ErrorMessage());
		}
	}
	 */
	snprintf(timestamp,TS_TIMESTAMP_SIZE,"%s",(char*)(dbconn->GetValue(0,0)));
	if(verbosity >= LOG_INFO) {
		syslog(LOG_INFO,"[timer] Initial timestamp: %s",timestamp);
		if(verbosity>=LOG_DEBUG) {
			syslog(LOG_DEBUG,"[timer] Timer is GO.");
		}
	}

	
	pthread_cond_broadcast(&timer_gonogo);
	// pthread_mutex_unlock(&timergonogolock);
	if(verbosity >= LOG_DEBUG) {
		syslog(LOG_DEBUG,"[timer] Activating signal handlers.");
	}

	signal(SIGINT,timerSigHandler);
	signal(SIGUSR1,timerSigHandler);
	signal(SIGTERM,timerSigHandler);
	
	if(verbosity>=LOG_DEBUG) {
		syslog(LOG_DEBUG,"[timer] Starting loop.");
	}
	while (run) {
		int slept=sleep(topts->interval);
		if(slept > 0) { // Awakened by a signal
			if (!run) {
				if(verbosity >= LOG_DEBUG) {
					syslog(LOG_DEBUG,"[timer] Exiting.");
				}
				break;
			}
		}
		pthread_mutex_lock(&timelock);
		dbconn->ExecCommandOk(query);
		snprintf(timestamp,TS_TIMESTAMP_SIZE,"%s",(char*)(dbconn->GetValue(0,0)));
		if(verbosity>=LOG_INFO) {
			syslog(LOG_INFO, "[timer] New timestamp: <%s>",
				timestamp);
		}
		pthread_mutex_unlock(&timelock);

	}
	if(verbosity >= LOG_INFO) {
		syslog(LOG_INFO,"[timer] Shutting down gracefully.");
	}
	pthread_exit(NULL);
}