In mbtask now use a thread for the ping function

This commit is contained in:
Michiel Broek 2003-11-30 19:13:29 +00:00
parent dadda455f2
commit bc9701f005
6 changed files with 156 additions and 133 deletions

View File

@ -13,6 +13,9 @@ v0.39.3 26-Nov-2003
mbsetup:
Removed binkp CRC settings.
mbtask:
The ping function now runs in a separate thread.
v0.39.2 21-Nov-2003 - 26-Nov-2003

View File

@ -64,6 +64,7 @@
#include <sys/mount.h>
#include <sys/wait.h>
#include <pwd.h>
#include <pthread.h>
#include <stddef.h>
#include <fcntl.h>

View File

@ -48,6 +48,8 @@
#include "mbtask.h"
#define NUM_THREADS 1 /* Max. nr of threads */
/*
* Global variables
@ -106,6 +108,16 @@ extern int isdn_free; /* ISDN lines free */
extern pp_list *pl; /* List of tty ports */
extern int ipmailers; /* TCP/IP mail sessions */
extern int tosswait; /* Toss wait timer */
extern pid_t mypid; /* Pid of daemon */
/*
* Global thread vaiables
*/
int thr_id[NUM_THREADS]; /* thread ID's */
pthread_t p_thread[NUM_THREADS]; /* thread's structure */
pthread_mutex_t p_mutex = PTHREAD_MUTEX_INITIALIZER; /* Ping mutex */
@ -932,7 +944,12 @@ void scheduler(void)
if (!TCFG.max_tcp && !pots_lines && !isdn_lines) {
Syslog('?', "ERROR: this system cannot connect to other systems, check setup");
}
/*
* Install ping thread
*/
thr_id[0] = pthread_create(&p_thread[0], NULL, (void (*))ping_thread, NULL);
/*
* Enter the mainloop (forever)
*/
@ -1093,7 +1110,7 @@ void scheduler(void)
oldsec = tm->tm_sec;
if (ptimer)
ptimer--;
check_ping();
// check_ping();
}
if (Processing) {
@ -1338,6 +1355,7 @@ int main(int argc, char **argv)
sprintf(cfgfn, "%s/etc/config.data", getenv("MBSE_ROOT"));
load_maincfg();
mypid = getpid();
Syslog(' ', " ");
Syslog(' ', "MBTASK v%s", VERSION);
sprintf(tcfgfn, "%s/etc/task.data", getenv("MBSE_ROOT"));
@ -1399,6 +1417,7 @@ int main(int argc, char **argv)
Syslog('?', "$Reopen of stderr to /dev/null failed");
_exit(MBERR_EXEC_FAILED);
}
mypid = getpid();
scheduler();
/* Not reached */
default:
@ -1415,6 +1434,7 @@ int main(int argc, char **argv)
}
free(lockfile);
Syslog('+', "Starting daemon with pid %d", frk);
pthread_exit(NULL);
exit(MBERR_OK);
}

View File

@ -38,8 +38,6 @@
/*
* Global variables
*/
@ -48,7 +46,6 @@ int ping_isocket; /* Ping socket */
int icmp_errs = 0; /* ICMP error counter */
extern int internet; /* Internet is down */
extern int rescan; /* Master rescan flag */
int pingstate = P_BOOT; /* Ping state */
struct in_addr paddr; /* Current ping address */
@ -257,9 +254,9 @@ int ping_receive(struct in_addr addr)
pfd.events = POLLIN;
/*
* 10 mSec is enough, this function is called at regular intervals.
* 100 mSec is enough, this function is called at regular intervals.
*/
if (poll(&pfd, 1, 10) < 0) {
if (poll(&pfd, 1, 100) < 0) {
if (icmp_errs < ICMP_MAX_ERRS)
Syslog('?', "$poll/select failed");
return -3;
@ -302,119 +299,6 @@ int ping_receive(struct in_addr addr)
void check_ping(void)
{
int rc = 0;
static int pingnr, pingresult[2];
static char pingaddress[41];
static time_t pingtime;
switch (pingstate) {
case P_BOOT: pingnr = 2;
pingstate = P_SENT;
pingresult[1] = pingresult[2] = internet = FALSE;
break;
case P_PAUSE: if (time(NULL) >= pingtime)
pingstate = P_SENT;
break;
case P_WAIT: if (time(NULL) >= pingtime) {
pingstate = P_ERROR;
if (icmp_errs < ICMP_MAX_ERRS)
Syslog('?', "ping: to %s timeout", pingaddress);
} else {
/*
* Quickly eat all packets not for us, we only want our
* packets and empty results (packet still underway).
*/
while ((rc = ping_receive(paddr)) == -1);
if (!rc) {
/*
* Reply received.
*/
rc = time(NULL) - (pingtime - 20);
if (rc > 10)
Syslog('+', "Ping: slow reply after %d seconds", rc);
pingresult[pingnr] = TRUE;
if (pingresult[1] || pingresult[2]) {
if (!internet) {
Syslog('!', "Internet connection is up");
internet = TRUE;
sem_set((char *)"scanout", TRUE);
CreateSema((char *)"is_inet");
rescan = TRUE;
}
icmp_errs = 0;
}
pingtime = time(NULL) + 5; // 5 secs pause until next ping
pingstate = P_PAUSE;
} else {
if (rc != -6) {
Syslog('p', "ping: recv %s id=%d rc=%d", pingaddress, id, rc);
pingstate = P_ERROR;
}
}
}
break;
case P_SENT: pingtime = time(NULL) + 10; // 10 secs timeout for pause.
if (pingnr == 1) {
pingnr = 2;
if (strlen(TCFG.isp_ping2)) {
sprintf(pingaddress, "%s", TCFG.isp_ping2);
} else {
pingresult[2] = FALSE;
pingstate = P_PAUSE;
break;
}
} else {
pingnr = 1;
if (strlen(TCFG.isp_ping1)) {
sprintf(pingaddress, "%s", TCFG.isp_ping1);
} else {
pingresult[1] = FALSE;
pingstate = P_PAUSE;
break;
}
}
pingtime = time(NULL) + 20; // 20 secs timeout for a real ping
if (inet_aton(pingaddress, &paddr)) {
rc = ping_send(paddr);
if (rc) {
if (icmp_errs++ < ICMP_MAX_ERRS)
Syslog('?', "ping: to %s rc=%d", pingaddress, rc);
pingstate = P_ERROR;
pingresult[pingnr] = FALSE;
} else {
pingstate = P_WAIT;
}
} else {
if (icmp_errs++ < ICMP_MAX_ERRS)
Syslog('?', "Ping address %d is invalid \"%s\"", pingnr, pingaddress);
pingstate = P_PAUSE;
}
break;
case P_ERROR: pingresult[pingnr] = FALSE;
if (pingresult[1] == FALSE && pingresult[2] == FALSE) {
icmp_errs++;
if (internet) {
Syslog('!', "Internet connection is down");
internet = FALSE;
sem_set((char *)"scanout", TRUE);
RemoveSema((char *)"is_inet");
rescan = TRUE;
}
}
pingtime = time(NULL) + 5; // 5 secs pause until next ping
pingstate = P_PAUSE;
break;
}
}
/*
* Create the ping socket, called from main() during init as root.
*/
@ -439,3 +323,123 @@ void init_pingsocket(void)
}
/*
* Ping thread
*/
void *ping_thread(void)
{
int rc = 0;
static int pingnr, pingresult[2];
static char pingaddress[41];
static time_t pingtime;
Syslog('p', "ping_thread: Start");
pingresult[1] = pingresult[2] = FALSE;
pingnr = 2;
internet = FALSE;
while (TRUE) {
/*
* Select new address to ping
*/
if (pingnr == 1) {
pingnr = 2;
if (strlen(TCFG.isp_ping2)) {
sprintf(pingaddress, "%s", TCFG.isp_ping2);
} else {
pingresult[2] = FALSE;
}
} else {
pingnr = 1;
if (strlen(TCFG.isp_ping1)) {
sprintf(pingaddress, "%s", TCFG.isp_ping1);
} else {
pingresult[1] = FALSE;
}
}
if (inet_aton(pingaddress, &paddr)) {
rc = ping_send(paddr);
if (rc) {
if (icmp_errs++ < ICMP_MAX_ERRS)
Syslog('?', "ping: to %s rc=%d", pingaddress, rc);
pingresult[pingnr] = FALSE;
} else {
if (internet)
pingtime = time(NULL) + 20;
else
pingtime = time(NULL) + 10;
while (TRUE) {
if (time(NULL) >= pingtime) {
pingresult[pingnr] = FALSE;
if (icmp_errs < ICMP_MAX_ERRS)
Syslog('?', "ping: to %s timeout", pingaddress);
break;
} else {
/*
* Quickly eat all packets not for us, we only want our
* packets and empty results (packet still underway).
*/
while ((rc = ping_receive(paddr)) == -1);
if (!rc) {
/*
* Reply received.
*/
rc = time(NULL) - (pingtime - 20);
if (rc > 5)
Syslog('+', "Ping: slow reply after %d seconds", rc);
pingresult[pingnr] = TRUE;
if (rc < 10)
sleep(10 - rc);
else
sleep(1);
break;
} else {
if (rc != -6) {
Syslog('p', "ping: recv %s id=%d rc=%d", pingaddress, id, rc);
pingresult[pingnr] = FALSE;
}
}
}
} /* while TRUE */
}
} else {
if (icmp_errs++ < ICMP_MAX_ERRS)
Syslog('?', "Ping address %d is invalid \"%s\"", pingnr, pingaddress);
sleep(10);
}
/*
* Evaluate the result of the ping test
*/
if (pingresult[1] == FALSE && pingresult[2] == FALSE) {
icmp_errs++;
if (internet) {
Syslog('!', "Internet connection is down");
internet = FALSE;
sem_set((char *)"scanout", TRUE);
RemoveSema((char *)"is_inet");
rescan = TRUE;
}
} else {
icmp_errs = 0;
if (!internet) {
Syslog('!', "Internet connection is up");
internet = TRUE;
sem_set((char *)"scanout", TRUE);
CreateSema((char *)"is_inet");
rescan = TRUE;
}
}
}
/* Never reached */
Syslog('p', "ping_thread: End");
pthread_exit(NULL);
}

View File

@ -1,12 +1,7 @@
/* $Id$ */
#ifndef _PING_H
#define _PING_H
typedef enum {P_BOOT, P_PAUSE, P_SENT, P_WAIT, P_ERROR} PINGSTATE;
#define _PING_H
/* $Id$ */
/*
* Defines.
@ -15,7 +10,7 @@ typedef enum {P_BOOT, P_PAUSE, P_SENT, P_WAIT, P_ERROR} PINGSTATE;
#define ICMP_MAX_ERRS 5
#define SET_SOCKA_LEN4(socka)
void check_ping(void);
void init_pingsocket(void);
void init_pingsocket(void);
void *ping_thread(void);
#endif

View File

@ -148,14 +148,14 @@ void Syslog(int grade, const char *format, ...)
if (lcnt) {
lcnt++;
fprintf(debugfile, "%c %s mbtask[%d] last message repeated %d times\n", lchr, date(), getpid(), lcnt);
fprintf(debugfile, "%c %s mbtask[%d] last message repeated %d times\n", lchr, date(), mypid, lcnt);
if (!debug)
fprintf(logfile, "%c %s mbtask[%d] last message repeated %d times\n", lchr, date(), getpid(), lcnt);
fprintf(logfile, "%c %s mbtask[%d] last message repeated %d times\n", lchr, date(), mypid, lcnt);
}
lcnt = 0;
if (!debug) {
fprintf(logfile, "%c %s mbtask[%d] ", grade, date(), getpid());
fprintf(logfile, "%c %s mbtask[%d] ", grade, date(), mypid);
fprintf(logfile, *outstr == '$' ? outstr+1 : outstr);
if (*outstr == '$')
fprintf(logfile, ": %s\n", strerror(errno));
@ -169,7 +169,7 @@ void Syslog(int grade, const char *format, ...)
free(logname);
}
fprintf(debugfile, "%c %s mbtask[%d] ", grade, date(), getpid());
fprintf(debugfile, "%c %s mbtask[%d] ", grade, date(), mypid);
fprintf(debugfile, *outstr == '$' ? outstr+1 : outstr);
if (*outstr == '$')
fprintf(debugfile, ": %s\n", strerror(errno));