Rewrote idleconn program to use libevent notification system.
This commit is contained in:
parent
2b34faf907
commit
7748d1e6e3
@ -1,3 +1,8 @@
|
|||||||
|
2008-01-31 Ted Bullock <tbullock@canada.com>
|
||||||
|
|
||||||
|
* src/idleconn.c: Complete rewrite to use libevent backend; slight
|
||||||
|
performance improvement thanks to use of libevent notification system
|
||||||
|
|
||||||
2007-11-16 Ted Bullock <tbullock@canada.com>
|
2007-11-16 Ted Bullock <tbullock@canada.com>
|
||||||
|
|
||||||
* configure.ac: Enable libevent dependancy
|
* configure.ac: Enable libevent dependancy
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
* New in version 1.0.0
|
* New in version 1.0.0
|
||||||
|
** Complete re-write of idleconn.c to use libevent notification system
|
||||||
|
|
||||||
* New in version 0.9.1:
|
* New in version 0.9.1:
|
||||||
** timer re-write to reduce memory and fix memory leaks
|
** timer re-write to reduce memory and fix memory leaks
|
||||||
|
@ -35,7 +35,11 @@
|
|||||||
#include <string.h> /* For strrchr() */
|
#include <string.h> /* For strrchr() */
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <event.h>
|
#include <event.h>
|
||||||
@ -48,14 +52,14 @@
|
|||||||
* Events allocated onto the heap
|
* Events allocated onto the heap
|
||||||
*/
|
*/
|
||||||
static struct List *active_events = NULL;
|
static struct List *active_events = NULL;
|
||||||
static struct List *inactive_events = NULL;
|
|
||||||
|
|
||||||
static const char *prog_name = NULL;
|
static const char *prog_name = NULL;
|
||||||
static unsigned long num_conn = 0, num_closed = 0;
|
static unsigned long num_conn = 0, num_closed = 0;
|
||||||
static struct timeval start_time;
|
static struct timeval start_time;
|
||||||
|
static struct sockaddr_in server_addr;
|
||||||
|
|
||||||
static char *server = NULL;
|
static char *server = NULL;
|
||||||
static int desired = 0;
|
static int desired = 0; /* Number of desired connections */
|
||||||
static int port = 0;
|
static int port = 0;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -64,6 +68,8 @@ cleanup()
|
|||||||
if (active_events != NULL) {
|
if (active_events != NULL) {
|
||||||
while (!is_list_empty(active_events)) {
|
while (!is_list_empty(active_events)) {
|
||||||
Any_Type a = list_pop(active_events);
|
Any_Type a = list_pop(active_events);
|
||||||
|
struct event *evsock = (struct event *) a.vp;
|
||||||
|
event_del(evsock);
|
||||||
free(a.vp);
|
free(a.vp);
|
||||||
}
|
}
|
||||||
list_free(active_events);
|
list_free(active_events);
|
||||||
@ -85,7 +91,9 @@ sigint_exit(int fd, short event, void *arg)
|
|||||||
printf("%s: total # conn. created = %lu, close() rate = %g conn/sec\n",
|
printf("%s: total # conn. created = %lu, close() rate = %g conn/sec\n",
|
||||||
prog_name, num_conn, num_closed / delta_t);
|
prog_name, num_conn, num_closed / delta_t);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
printf("%s: caught SIGINT... Exiting.\n", __func__);
|
printf("%s: caught SIGINT... Exiting.\n", __func__);
|
||||||
|
#endif /* DEBUG */
|
||||||
|
|
||||||
evdns_shutdown(0);
|
evdns_shutdown(0);
|
||||||
event_del(signal_int);
|
event_del(signal_int);
|
||||||
@ -93,11 +101,45 @@ sigint_exit(int fd, short event, void *arg)
|
|||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
reconnect(int sd, short event, void *arg)
|
||||||
|
{
|
||||||
|
struct sockaddr_in sin = server_addr;
|
||||||
|
struct event *evsock = (struct event *) arg;
|
||||||
|
|
||||||
|
close(sd);
|
||||||
|
num_closed++;
|
||||||
|
|
||||||
|
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
if (sd == -1) {
|
||||||
|
perror("socket");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connect(sd, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
|
||||||
|
perror("connect");
|
||||||
|
cleanup();
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
event_set(evsock, sd, EV_READ, reconnect, evsock);
|
||||||
|
event_add(evsock, NULL);
|
||||||
|
num_conn++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For the explanation of these parameters, please refer to the libevent evdns
|
||||||
|
* callback API
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
dns_lookup_callback(int result, char type, int count, int ttl, void *addresses,
|
dns_lookup_callback(int result, char type, int count, int ttl, void *addresses,
|
||||||
void *arg)
|
void *arg)
|
||||||
{
|
{
|
||||||
uint8_t i;
|
uint32_t i;
|
||||||
|
uint8_t oct[4];
|
||||||
|
struct in_addr *address_list = (struct in_addr *) addresses;
|
||||||
|
|
||||||
if (result != DNS_ERR_NONE) {
|
if (result != DNS_ERR_NONE) {
|
||||||
printf("DNS Lookup: result(%d)\n",
|
printf("DNS Lookup: result(%d)\n",
|
||||||
@ -105,22 +147,55 @@ dns_lookup_callback(int result, char type, int count, int ttl, void *addresses,
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Resolved %s\n", server);
|
memset(&server_addr, 0, sizeof(server_addr));
|
||||||
|
server_addr.sin_family = AF_INET;
|
||||||
|
server_addr.sin_port = htons(port);
|
||||||
|
server_addr.sin_addr = address_list[0];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Echo the resolved address
|
||||||
|
*/
|
||||||
|
printf("Resolved %s\n\t(%s)\n", server, inet_ntoa(address_list[0]));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open the number of `desired` connections
|
||||||
|
*/
|
||||||
|
for (i = 0; i < desired; i++) {
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
int sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
struct event *evsock = NULL;
|
||||||
|
|
||||||
|
if (sd == -1) {
|
||||||
|
perror("socket");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
sin = server_addr;
|
||||||
|
|
||||||
|
if (connect(sd, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
|
||||||
|
perror("connect");
|
||||||
|
cleanup();
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
evsock = (struct event *) malloc(sizeof(struct event));
|
||||||
|
|
||||||
|
if (evsock == NULL) {
|
||||||
|
cleanup();
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
event_set(evsock, sd, EV_READ, reconnect, evsock);
|
||||||
|
list_push(active_events, (Any_Type) (void *) evsock);
|
||||||
|
num_conn++;
|
||||||
|
|
||||||
|
event_add(evsock, NULL);
|
||||||
|
|
||||||
for (i = 0; i < count; ++i) {
|
|
||||||
uint32_t *address_list = (uint32_t *) addresses;
|
|
||||||
uint8_t oct[4];
|
|
||||||
oct[0] = (uint8_t) (address_list[i] & 0x000000ff);
|
|
||||||
oct[1] = (uint8_t) ((address_list[i] & 0x0000ff00) >> 8);
|
|
||||||
oct[2] = (uint8_t) ((address_list[i] & 0x00ff0000) >> 16);
|
|
||||||
oct[3] = (uint8_t) ((address_list[i] & 0xff000000) >> 24);
|
|
||||||
printf("\t(%u.%u.%u.%u)\n", oct[0], oct[1], oct[2], oct[3]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct event signal_int;
|
struct event signal_int;
|
||||||
@ -129,10 +204,6 @@ main(int argc, char *argv[])
|
|||||||
if (active_events == NULL)
|
if (active_events == NULL)
|
||||||
goto init_failure;
|
goto init_failure;
|
||||||
|
|
||||||
inactive_events = list_create();
|
|
||||||
if (inactive_events == NULL)
|
|
||||||
goto init_failure;
|
|
||||||
|
|
||||||
event_init();
|
event_init();
|
||||||
evdns_init();
|
evdns_init();
|
||||||
|
|
||||||
@ -181,4 +252,9 @@ main(int argc, char *argv[])
|
|||||||
init_failure:
|
init_failure:
|
||||||
cleanup();
|
cleanup();
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Should never reach here
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user