diff --git a/ChangeLog b/ChangeLog index bee4c45b..4d6e11e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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 diff --git a/mbtask/libs.h b/mbtask/libs.h index 405306c3..63b2ea30 100644 --- a/mbtask/libs.h +++ b/mbtask/libs.h @@ -64,6 +64,7 @@ #include #include #include +#include #include #include diff --git a/mbtask/mbtask.c b/mbtask/mbtask.c index 6705eae8..babe7ded 100644 --- a/mbtask/mbtask.c +++ b/mbtask/mbtask.c @@ -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); } diff --git a/mbtask/ping.c b/mbtask/ping.c index dc516156..99641f95 100644 --- a/mbtask/ping.c +++ b/mbtask/ping.c @@ -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); +} + + + diff --git a/mbtask/ping.h b/mbtask/ping.h index 9fd5127e..580c658f 100644 --- a/mbtask/ping.h +++ b/mbtask/ping.h @@ -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 diff --git a/mbtask/taskutil.c b/mbtask/taskutil.c index 877b612d..08af684b 100644 --- a/mbtask/taskutil.c +++ b/mbtask/taskutil.c @@ -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));