Browse Source

Rewrote idleconn program to use libevent notification system.

ahc_fix_select
tedbullock 17 years ago
parent
commit
7748d1e6e3
3 changed files with 100 additions and 18 deletions
  1. +5
    -0
      httperf/ChangeLog
  2. +1
    -0
      httperf/NEWS
  3. +94
    -18
      httperf/src/idleconn.c

+ 5
- 0
httperf/ChangeLog View File

@@ -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>

* configure.ac: Enable libevent dependancy


+ 1
- 0
httperf/NEWS View File

@@ -1,4 +1,5 @@
* New in version 1.0.0
** Complete re-write of idleconn.c to use libevent notification system

* New in version 0.9.1:
** timer re-write to reduce memory and fix memory leaks


+ 94
- 18
httperf/src/idleconn.c View File

@@ -35,7 +35,11 @@
#include <string.h> /* For strrchr() */
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <inttypes.h>

#include <sys/time.h>
#include <event.h>
@@ -48,14 +52,14 @@
* Events allocated onto the heap
*/
static struct List *active_events = NULL;
static struct List *inactive_events = NULL;

static const char *prog_name = NULL;
static unsigned long num_conn = 0, num_closed = 0;
static struct timeval start_time;
static struct sockaddr_in server_addr;

static char *server = NULL;
static int desired = 0;
static int desired = 0; /* Number of desired connections */
static int port = 0;

static void
@@ -64,6 +68,8 @@ cleanup()
if (active_events != NULL) {
while (!is_list_empty(active_events)) {
Any_Type a = list_pop(active_events);
struct event *evsock = (struct event *) a.vp;
event_del(evsock);
free(a.vp);
}
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",
prog_name, num_conn, num_closed / delta_t);

#ifdef DEBUG
printf("%s: caught SIGINT... Exiting.\n", __func__);
#endif /* DEBUG */

evdns_shutdown(0);
event_del(signal_int);
@@ -93,11 +101,45 @@ sigint_exit(int fd, short event, void *arg)
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
dns_lookup_callback(int result, char type, int count, int ttl, void *addresses,
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) {
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);
}

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];

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]);
}
/*
* 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);

}
}

void
int
main(int argc, char *argv[])
{
struct event signal_int;
@@ -129,10 +204,6 @@ main(int argc, char *argv[])
if (active_events == NULL)
goto init_failure;

inactive_events = list_create();
if (inactive_events == NULL)
goto init_failure;

event_init();
evdns_init();

@@ -181,4 +252,9 @@ main(int argc, char *argv[])
init_failure:
cleanup();
exit(EXIT_FAILURE);

/*
* Should never reach here
*/
return 0;
}

Loading…
Cancel
Save