[Listener] Better handling of threads

Fix thread headers, check the return value of pthread_create(), and wait
for the threads at the end of the program.
This commit is contained in:
Matteo Cypriani 2011-03-24 08:30:54 +01:00
parent fd4b51aeff
commit f71a4650e2
2 changed files with 90 additions and 13 deletions

View File

@ -69,6 +69,7 @@ enum {MODE_ACTIVE = 'a', MODE_PASSIVE = 'p', MODE_MIXED = 'm'} ;
#define ERR_OPENING_IFACE 2 // Error when opening capture interface
#define ERR_BAD_USAGE 3 // Bad program call
#define ERR_PARSING_CONFIG_FILE 4 // Error reading the configuration file
#define ERR_CREATING_THREAD 6 // Error creating a thread
/* Function headers */
@ -81,7 +82,7 @@ void print_configuration(void) ;
#endif // DEBUG
#ifdef USE_PTHREAD
void keep_mode_monitor(char *iface) ;
void* keep_mode_monitor(void *iface) ;
#endif // USE_PTHREAD
int capture(void) ;
void read_packet(u_char *args, const struct pcap_pkthdr *header,
@ -90,8 +91,8 @@ void get_mac_addr(char *eth, uint8_t mac_bytes[6]) ;
void get_ip_addr(char *eth, char *ip_bytes) ;
#ifdef USE_PTHREAD
void autocalibrate(void) ;
void autocalibrate_hello(void) ;
void* autocalibrate(void *NULL_value) ;
void* autocalibrate_hello(void *NULL_value) ;
void send_autocalibration_request(void) ;
uint_fast16_t make_packet(uint8_t **packet) ;
#endif // USE_PTHREAD

View File

@ -104,19 +104,89 @@ int main(int argc, char *argv[])
#ifdef USE_PTHREAD
/* Set up threads */
if (GET_KEEP_MONITOR())
pthread_create(&keep_monitor_thread, NULL,
(void *) &keep_mode_monitor, GET_WIFI_IFACE()) ;
{
ret = pthread_create(&keep_monitor_thread, NULL,
&keep_mode_monitor, GET_WIFI_IFACE()) ;
if (ret != 0)
{
perror("Cannot create keep monitor thread") ;
ret = ERR_CREATING_THREAD ;
goto exit ;
}
}
if (GET_AUTOCALIBRATION())
{
pthread_create(&autocalibration_thread, NULL,
(void *) &autocalibrate, NULL) ;
pthread_create(&autocalibration_hello_thread, NULL,
(void *) &autocalibrate_hello, NULL) ;
ret = pthread_create(&autocalibration_thread, NULL,
&autocalibrate, NULL) ;
if (ret != 0)
{
perror("Cannot create autocalibration thread") ;
ret = ERR_CREATING_THREAD ;
goto exit ;
}
ret = pthread_create(&autocalibration_hello_thread, NULL,
&autocalibrate_hello, NULL) ;
if (ret != 0)
{
perror("Cannot create autocalibration hello thread") ;
ret = ERR_CREATING_THREAD ;
goto exit ;
}
}
#endif // USE_PTHREAD
ret = capture() ; // Capture loop
/* Wait for the threads to terminate */
if (GET_KEEP_MONITOR())
{
fprintf(stderr, "Waiting for the keep mode monitor thread... ") ;
if (pthread_join(keep_monitor_thread, NULL) != 0)
perror("Cannot join keep mode monitor thread") ;
else
fprintf(stderr, "OK.\n") ;
}
if (GET_AUTOCALIBRATION())
{
// We must cancel this thread because it can be blocked on the
// recvfrom() call:
fprintf(stderr,
"Cancelling the autocalibration thread... ") ;
if (pthread_cancel(autocalibration_thread) != 0)
perror("Cannot cancel autocalibration thread") ;
else
fprintf(stderr, "OK.\n") ;
fprintf(stderr,
"Waiting for the autocalibration thread... ") ;
if (pthread_join(autocalibration_thread, NULL) != 0)
perror("Cannot join autocalibration thread") ;
else
fprintf(stderr, "OK.\n") ;
// We must cancel this thread if we do not want to wait
// autocalibration_hello_delay seconds (in the worst case):
fprintf(stderr,
"Cancelling the autocalibration hello thread... ") ;
if (pthread_cancel(autocalibration_hello_thread) != 0)
perror("Cannot cancel autocalibration hello thread") ;
else
fprintf(stderr, "OK.\n") ;
fprintf(stderr,
"Waiting for the autocalibration hello thread... ") ;
if (pthread_join(autocalibration_hello_thread, NULL) != 0)
perror("Cannot join autocalibration hello thread") ;
else
fprintf(stderr, "OK.\n") ;
}
/* Last cleaning tasks */
exit:
#ifdef USE_CONFIG_FILE
cfg_free(cfg) ; // Clean configuration
#endif // USE_CONFIG_FILE
@ -491,7 +561,7 @@ void print_configuration()
* Thread function. Switches interface 'iface' to monitor mode every
* second.
*/
void keep_mode_monitor(char *iface)
void* keep_mode_monitor(void *iface)
{
if (GET_VERBOSE())
fprintf(stderr, "Thread for keeping monitor mode launched.\n") ;
@ -499,9 +569,11 @@ void keep_mode_monitor(char *iface)
while (run)
{
// Switch the interface to monitor mode:
owl_iface_mode_monitor(iface) ;
owl_iface_mode_monitor((char*) iface) ;
sleep(1) ; // Wait for 1 second
}
pthread_exit(NULL) ;
}
#endif // USE_PTHREAD
@ -958,7 +1030,7 @@ void get_ip_addr(char *eth, char ip[16])
/* *** Autocalibration functions *** */
#ifdef USE_PTHREAD
void autocalibrate_hello()
void* autocalibrate_hello(void *NULL_value)
{
int send_sockfd ;
struct sockaddr_in serv;
@ -982,11 +1054,13 @@ void autocalibrate_hello()
}
(void) close(send_sockfd) ;
pthread_exit(NULL_value) ;
}
void autocalibrate()
void* autocalibrate(void *NULL_value)
{
int nread ; // recvfrom return value
struct sockaddr_in client; // UDP client structure
@ -1039,6 +1113,8 @@ void autocalibrate()
}
(void) close(listen_sockfd) ;
pthread_exit(NULL_value) ;
}