Permalink
Browse files

Further reworking of asynch NL

  • Loading branch information...
1 parent f68e45f commit ecc567bd16787d2072eaed8c6edae50a5085dbf1 ec429 committed Jan 12, 2012
Showing with 97 additions and 86 deletions.
  1. +20 −7 input.c
  2. +33 −43 irc.c
  3. +13 −6 irc.h
  4. +31 −30 quirc.c
View
@@ -704,9 +704,14 @@ int cmd_handle(char *inp, char **qmsg, fd_set *master, int *fdmax) // old state=
char dstr[30+strlen(server)+strlen(newport)];
sprintf(dstr, "Connecting to %s on port %s...", server, newport);
#if ASYNCH_NL
- irc_connect(server, newport, master, fdmax);
- if(!quiet) add_to_buffer(0, c_status, dstr, "/server: ");
- if(force_redraw<3) redraw_buffer();
+ __attribute__((unused)) int *p= fdmax;
+ nl_list *nl=irc_connect(server, newport);
+ if(nl)
+ {
+ nl->reconn_b=0;
+ if(!quiet) add_to_buffer(0, c_status, dstr, "/server: ");
+ if(force_redraw<3) redraw_buffer();
+ }
#else
int serverhandle=irc_connect(server, newport, master, fdmax);
if(serverhandle)
@@ -752,10 +757,18 @@ int cmd_handle(char *inp, char **qmsg, fd_set *master, int *fdmax) // old state=
char dstr[30+strlen(bufs[bufs[cbuf].server].bname)+strlen(newport)];
sprintf(dstr, "Connecting to %s on port %s...", bufs[bufs[cbuf].server].bname, newport);
#if ASYNCH_NL
- irc_connect(bufs[bufs[cbuf].server].bname, newport, master, fdmax);
- nl_reconn_b=bufs[cbuf].server;
- if(!quiet) add_to_buffer(bufs[cbuf].server, c_status, dstr, "/server: ");
- if(force_redraw<3) redraw_buffer();
+ nl_list *nl=irc_connect(bufs[bufs[cbuf].server].bname, newport);
+ if(nl)
+ {
+ nl->reconn_b=bufs[cbuf].server;
+ if(!quiet) add_to_buffer(bufs[cbuf].server, c_status, dstr, "/server: ");
+ if(force_redraw<3) redraw_buffer();
+ }
+ else
+ {
+ add_to_buffer(bufs[cbuf].server, c_err, "malloc failure (see status)", "/server: ");
+ if(force_redraw<3) redraw_buffer();
+ }
#else /* ASYNCH_NL */
int serverhandle=irc_connect(bufs[bufs[cbuf].server].bname, newport, master, fdmax);
if(serverhandle)
View
@@ -19,54 +19,50 @@ void handle_signals(int sig)
}
#if ASYNCH_NL
-int irc_connect(char *server, const char *portno, __attribute__((unused)) fd_set *master, __attribute__((unused)) int *fdmax)
+nl_list *irc_connect(char *server, const char *portno)
{
- if(nl_nreqs) // TODO handle it anyway, by extending the list
- {
- add_to_buffer(0, c_err, "DNS lookup already in progress (/nlcancel to cancel)", "/connect: ");
- return(-1);
- }
// Look up server
struct addrinfo *hints=malloc(sizeof(struct addrinfo));
if(!hints)
{
add_to_buffer(0, c_err, strerror(errno), "malloc: ");
- return(-1);
+ return(NULL);
}
memset(hints, 0, sizeof(*hints));
hints->ai_family=AF_INET;
hints->ai_socktype = SOCK_STREAM; // TCP stream sockets
- nl_details=malloc(sizeof(struct gaicb *));
+ struct gaicb *nl_details=malloc(sizeof(struct gaicb));
if(!nl_details)
{
add_to_buffer(0, c_err, strerror(errno), "malloc: ");
- return(-1);
+ return(NULL);
}
- *nl_details=malloc(sizeof(struct gaicb));
- if(!*nl_details)
+ nl_list *nl=malloc(sizeof(nl_list));
+ if(!nl)
{
add_to_buffer(0, c_err, strerror(errno), "malloc: ");
free(nl_details);
- return(-1);
- }
- **nl_details=(struct gaicb){.ar_name=strdup(server), .ar_service=strdup(portno), .ar_request=hints};
- nl_nreqs=1;
- nl_nsat=0;
- getaddrinfo_a(GAI_NOWAIT, nl_details, 1, &(struct sigevent){.sigev_notify=SIGEV_SIGNAL, .sigev_signo=SIGUSR1});
- return(0);
+ return(NULL);
+ }
+ *nl=(nl_list){.nl_details=nl_details, .autoent=NULL, .reconn_b=0, .next=nl_active, .prev=NULL};
+ *nl_details=(struct gaicb){.ar_name=strdup(server), .ar_service=strdup(portno), .ar_request=hints};
+ if(nl_active) nl_active->prev=nl;
+ nl_active=nl;
+ getaddrinfo_a(GAI_NOWAIT, &nl->nl_details, 1, &(struct sigevent){.sigev_notify=SIGEV_SIGNAL, .sigev_signo=SIGUSR1});
+ return(nl_active);
}
-int irc_conn_found(fd_set *master, int *fdmax)
+int irc_conn_found(nl_list **list, fd_set *master, int *fdmax)
{
int serverhandle=0;
struct addrinfo *servinfo;
- int i;
- for(i=0;i<nl_nreqs;i++)
+ while(*list)
{
- if(gai_error(nl_details[i])) continue;
- servinfo=nl_details[i]->ar_result;
- break;
+ if(gai_error((*list)->nl_details)) *list=(*list)->next;
+ else break;
}
+ if(!*list) return(0); // 0 indicates failure as rv is new serverhandle value
+ servinfo=(*list)->nl_details->ar_result;
#else /* ASYNCH_NL */
int irc_connect(char *server, const char *portno, fd_set *master, int *fdmax)
@@ -125,17 +121,6 @@ int irc_connect(char *server, const char *portno, fd_set *master, int *fdmax)
}
freeaddrinfo(servinfo);
servinfo=NULL;
-#if ASYNCH_NL
- free((char *)nl_details[i]->ar_name);
- free((char *)nl_details[i]->ar_service);
- free((void *)nl_details[i]->ar_request);
- if(++nl_nsat>=nl_nreqs)
- {
- free(nl_details);
- nl_details=NULL;
- nl_nreqs=nl_nsat=0;
- }
-#endif
FD_SET(serverhandle, master);
*fdmax=max(*fdmax, serverhandle);
return(serverhandle);
@@ -175,13 +160,16 @@ int irc_conn_rest(int b, char *nick, char *username, char *passwd, char *fullnam
int autoconnect(fd_set *master, int *fdmax, servlist *serv) // XXX broken in the face of asynch nl
{
servlist *curr=serv;
- nreqs=nsats=0;
- while(curr)
- {
- nreqs++;
- curr=curr->next;
- }
- return(0);
+ if(!curr) return(0);
+ #if ASYNCH_NL
+ char cstr[36+strlen(serv->name)+strlen(serv->portno)];
+ sprintf(cstr, "Connecting to %s on port %s...", serv->name, serv->portno);
+ nl_list *list=irc_connect(serv->name, serv->portno);
+ if(!list) return(autoconnect(master, fdmax, serv->next));
+ if(!quiet) add_to_buffer(0, c_status, cstr, "auto: ");
+ list->reconn_b=0;
+ list->autoent=serv;
+ #else /* ASYNCH_NL */
char cstr[36+strlen(serv->name)+strlen(serv->portno)];
sprintf(cstr, "Connecting to %s on port %s...", serv->name, serv->portno);
if(!quiet) add_to_buffer(0, c_status, cstr, "auto: ");
@@ -200,7 +188,9 @@ int autoconnect(fd_set *master, int *fdmax, servlist *serv) // XXX broken in the
if(!quiet) add_to_buffer(cbuf, c_status, cstr, "auto: ");
if(force_redraw<3) redraw_buffer();
}
- return(nreqs);
+ #endif /* ASYNCH_NL */
+ autoconnect(master, fdmax, serv->next);
+ return(1);
}
int irc_tx(int fd, char * packet)
View
@@ -56,13 +56,20 @@ volatile sig_atomic_t sigpipe, sigwinch, sigusr1;
void handle_signals(int); // handles sigpipe, sigwinch and sigusr1
-int irc_connect(char *server, const char *portno, fd_set *master, int *fdmax); // non-blocking
#if ASYNCH_NL
-int nl_nreqs;
-int nl_nsat;
-struct gaicb **nl_details;
-int nl_reconn_b;
-int irc_conn_found(fd_set *master, int *fdmax); // non-blocking; call this when the getaddrinfo_a() has finished
+typedef struct _nl_list
+{
+ struct gaicb *nl_details;
+ int reconn_b;
+ servlist *autoent; // filled out by autoconnect
+ struct _nl_list *prev, *next;
+}
+nl_list;
+nl_list *nl_active;
+nl_list *irc_connect(char *server, const char *portno); // non-blocking NL
+int irc_conn_found(nl_list **list, fd_set *master, int *fdmax); // non-blocking; call this when the getaddrinfo_a() has finished
+#else
+int irc_connect(char *server, const char *portno, fd_set *master, int *fdmax); // non-blocking
#endif
int irc_conn_rest(int b, char *nick, char *username, char *passwd, char *fullname); // call this when the non-blocking connect() has finished
int autoconnect(fd_set *master, int *fdmax, servlist *serv);
View
@@ -175,7 +175,7 @@ int main(int argc, char *argv[])
FD_ZERO(&master);
FD_SET(STDIN_FILENO, &master);
int fdmax=STDIN_FILENO;
- if((!autoconnect(&master, &fdmax, &servs))&&(!quiet))
+ if((!autoconnect(&master, &fdmax, servs))&&(!quiet))
add_to_buffer(0, c_status, "Not connected - use /server to connect", "");
iline inp={{NULL, 0, 0}, {NULL, 0, 0}};
in_update(inp);
@@ -206,41 +206,35 @@ int main(int argc, char *argv[])
#if ASYNCH_NL
if(sigusr1)
{
- int i;
- for(i=0;i<nl_nreqs;i++)
+ sigusr1=0; // no race condition, because after this point we loop over the whole nl_list
+ int serverhandle;
+ nl_list *list=nl_active;
+ while((serverhandle=irc_conn_found(&list, &master, &fdmax))&&list)
{
- if(!gai_error(nl_details[i])) break;
- }
- char *server=strdup(nl_details[i]->ar_name);
- if(!server) server="server";
- const char *port=nl_details[i]->ar_service;
- if(!port) port="port";
- char dstr[32+strlen(server)+strlen(port)];
- sprintf(dstr, "Found %s, connecting on %s...", server, port);
- if(!quiet) add_to_buffer(nl_reconn_b, c_status, dstr, "/connect: ");
- if(force_redraw<3) redraw_buffer();
- if(nl_reconn_b)
- {
- int serverhandle=irc_conn_found(&master, &fdmax);
- if(serverhandle)
+ const char *server=list->nl_details->ar_name;
+ if(!server) server="server";
+ const char *port=list->nl_details->ar_service;
+ if(!port) port="port";
+ char dstr[32+strlen(server)+strlen(port)];
+ sprintf(dstr, "Found %s, connecting on %s...", server, port);
+ if(!quiet) add_to_buffer(list->reconn_b, c_status, dstr, "/server: ");
+ if(force_redraw<3) redraw_buffer();
+ if(list->reconn_b)
{
- bufs[nl_reconn_b].handle=serverhandle;
+ bufs[list->reconn_b].handle=serverhandle;
int b2;
for(b2=1;b2<nbufs;b2++)
{
- if(bufs[b2].server==nl_reconn_b)
+ if(bufs[b2].server==list->reconn_b)
bufs[b2].handle=serverhandle;
}
- bufs[cbuf].conninpr=true;
- free(bufs[cbuf].realsname);
- bufs[cbuf].realsname=NULL;
- if(!quiet) add_to_buffer(cbuf, c_status, dstr, "/server: ");
+ bufs[list->reconn_b].conninpr=true;
+ free(bufs[list->reconn_b].realsname);
+ bufs[list->reconn_b].realsname=NULL;
+ if(list->autoent)
+ bufs[list->reconn_b].autoent=list->autoent;
}
- }
- else
- {
- int serverhandle=irc_conn_found(&master, &fdmax);
- if(serverhandle)
+ else
{
bufs=(buffer *)realloc(bufs, ++nbufs*sizeof(buffer));
init_buffer(nbufs-1, SERVER, server, buflines);
@@ -249,10 +243,17 @@ int main(int argc, char *argv[])
bufs[cbuf].nick=strdup(nick);
bufs[cbuf].server=cbuf;
bufs[cbuf].conninpr=true;
+ if(list->autoent)
+ bufs[cbuf].autoent=list->autoent;
}
+ free((char *)list->nl_details->ar_name);
+ free((char *)list->nl_details->ar_service);
+ freeaddrinfo((void *)list->nl_details->ar_request);
+ if(list->prev) list->prev->next=list->next;
+ else nl_active=list->next;
+ if(list->next) list->next->prev=list->prev;
+ free(list);
}
- free(server);
- sigusr1=0; // there would be a race condition here, but we don't allow concurrent name lookups anyway so it's safe
}
#endif
// propagate liveness values into dependent tabs, and ping idle connections

0 comments on commit ecc567b

Please sign in to comment.