From: Ian Jackson Date: Thu, 22 Apr 2010 19:57:20 +0000 (+0100) Subject: wip compile X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=inn-innduct.git;a=commitdiff_plain;h=8b7074062790fe3362d1fa7ca28bf68d84820e03;ds=sidebyside wip compile many fixes TODO item: must add stuff to LIST_ADD* to check that ISNODE is at right bit of struct (start) etc. --- diff --git a/backends/innduct.c b/backends/innduct.c index b812470..a5bb448 100644 --- a/backends/innduct.c +++ b/backends/innduct.c @@ -145,12 +145,13 @@ perl -ne 'print if m/-8\<-/..m/-\>8-/; print "\f" if m/-\^L-/' backends/innduct. * */ +/*============================== PROGRAM ==============================*/ + #define _GNU_SOURCE #include "config.h" #include "storage.h" -#include "oop.h" -#include "oop-read.h" +#include "nntp.h" #include #include @@ -163,6 +164,10 @@ perl -ne 'print if m/-8\<-/..m/-\>8-/; print "\f" if m/-\^L-/' backends/innduct. #include #include #include +#include + +#include +#include /*----- general definitions, probably best not changed -----*/ @@ -174,8 +179,48 @@ perl -ne 'print if m/-8\<-/..m/-\>8-/; print "\f" if m/-\^L-/' backends/innduct. #define INNDCOMMCHILD_ESTATUS_FAIL 6 #define INNDCOMMCHILD_ESTATUS_NONESUCH 7 +/*----- doubly linked lists -----*/ + +#define ISNODE(T) struct { T *succ, *pred; } node +#define DEFLIST(T) typedef struct { T *head, *tail, *tp; int count; } T##List + +#define NODE(n) ((struct node*)&(n)->node) + +#define LIST_ADDHEAD(l,n) \ + (list_addhead((struct list*)&(l), NODE((n))), (void)(l).count++) +#define LIST_ADDTAIL(l,n) \ + (list_addtail((struct list*)&(l), NODE((n))), (void)(l).count++) + +#define LIST_REMHEAD(l) \ + ((l).count ? ((l).count--, (void*)list_remhead((struct list*)&(l))) : 0) +#define LIST_REMTAIL(l) \ + ((l).count ? ((l).count--, (void*)list_remtail((struct list*)&(l))) : 0) +#define LIST_REMOVE(l,n) \ + (list_remove(NODE((n))), (void)(l).count--) +#define LIST_INSERT(l,n,pred) \ + (list_insert((struct list*)&(l), NODE((n)), NODE((pred))), (void)(l).count++) + +/*----- type predeclarations -----*/ + typedef struct Conn Conn; typedef struct Article Article; +typedef enum StateMachineState StateMachineState; + +DEFLIST(Conn); +DEFLIST(Article); + +/*----- function predeclarations -----*/ + +static void conn_check_work(Conn *conn); + +static int filemon_init(void); +static void filemon_setfile(int mainfeed_fd, const char *mainfeed_path); +static void filemon_callback(void); + +static void conn_assign_one_article(ConnList *connlist, Conn **last_assigned); +static void statemc_setstate(StateMachineState newsms, int periods, + const char *forlog, const char *why); +static void check_master_queue(void); /*----- configuration options -----*/ @@ -199,28 +244,6 @@ static double nocheck_decay; /* computed in main from _articles */ static int nocheck, nocheck_reported; -/*----- doubly linked lists -----*/ - -#define ISNODE(T) T *next, *back; -#define LIST(T) struct { T *head, *tail, *tailpred; int count; } - -#define NODE(n) ((struct node*)&(n)->head) - -#define LIST_ADDHEAD(l,n) \ - (list_addhead((struct list*)&(l), NODE((n))), (void)(l).count++) -#define LIST_ADDTAIL(l,n) \ - (list_addtail((struct list*)&(l), NODE((n))), (void)(l).count++) - -#define LIST_REMHEAD(l) \ - ((l).count ? ((l).count--, (void*)list_remhead((struct list*)&(l))) : 0) -#define LIST_REMTAIL(l) \ - ((l).count ? ((l).count--, (void*)list_remtail((struct list*)&(l))) : 0) -#define LIST_REMOVE(l,n) \ - (list_remove(NODE((n))), (void)(l).count--) -#define LIST_INSERT(l,n,pred) \ - (list_insert((struct list*)&(l), NODE((n)), NODE((pred))), (void)(l).count++) - - /*----- statistics -----*/ typedef enum { /* in queue in conn->sent */ @@ -291,6 +314,7 @@ typedef struct InputFile { } InputFile; struct Article { + ISNODE(Article); ArtState state; int midlen; InputFile *ipf; @@ -308,10 +332,10 @@ struct Article { X(DROPPING) \ X(DROPPED) -typedef enum { +enum StateMachineState { #define SMS_DEF_ENUM(s) sm_##s, SMS_LIST(SMS_DEF_ENUM) -} StateMachineState; +}; static const char *sms_names[]= { #define SMS_DEF_NAME(s) #s , @@ -322,8 +346,8 @@ static const char *sms_names[]= { struct Conn { ISNODE(Conn); int fd, max_queue, stream; - LIST(Article) queue; /* not yet told peer, or CHECK said send it */ - LIST(Article) sent; /* offered/transmitted - in xmit or waiting reply */ + ArticleList queue; /* not yet told peer, or CHECK said send it */ + ArticleList sent; /* offered/transmitted - in xmit or waiting reply */ struct iovec xmit[CONNIOVS]; XmitDetails xmitd[CONNIOVS]; int xmitu; @@ -334,9 +358,9 @@ struct Conn { static oop_source *loop; -static int nconns; -static LIST(Conn) idle, working, full; -static LIST(Article) *queue; +static int nconns, until_connect; +static ConnList idle, working, full; +static ArticleList queue; static char *path_lock, *path_flushing, *path_defer; @@ -349,17 +373,6 @@ static InputFile *main_input_file, *flushing_input_file, *backlog_input_file; static int sm_period_counter; -/*----- function predeclarations -----*/ - -static void conn_check_work(Conn *conn); - -static int filemon_init(void); -static void filemon_setfile(int mainfeed_fd, const char *mainfeed_path); -static void filemon_callback(void); - -static void statemc_setstate(StateMachineState newsms, int periods, - const char *forlog, const char *why); - /*========== logging ==========*/ static void logcore(int sysloglevel, const char *fmt, ...) @@ -515,6 +528,13 @@ static void xlstat_isreg(const char *path, struct stat *stab, check_isreg(stab, path, what); } +static void setnonblock(int fd, int nonblocking) { + int r= fcntl(fd, F_GETFL); if (r<0) sysdie("setnonblocking fcntl F_GETFL"); + if (nonblocking) r |= O_NONBLOCK; + else r &= ~O_NONBLOCK; + r= fcntl(fd, F_SETFL, r); if (r<0) sysdie("setnonblocking fcntl F_SETFL"); +} + static int samefile(const struct stat *a, const struct stat *b) { assert(S_ISREG(a->st_mode)); assert(S_ISREG(b->st_mode)); @@ -569,11 +589,11 @@ static void *connchild_event(oop_source *lp, int fd, oop_event e, void *u) { assert(got==connecting_child); connecting_child= 0; if (WIFEXITED(status) && - (WEXITSTATUS(status) != 0 + (WEXITSTATUS(status) != 0 && WEXITSTATUS(status) != CONNCHILD_ESTATUS_STREAM && WEXITSTATUS(status) != CONNCHILD_ESTATUS_NOSTREAM)) { /* child already reported the problem */ - } else if (WIFSIGNALED(status) && WTERMSIG(status) == SIGALARM) { + } else if (WIFSIGNALED(status) && WTERMSIG(status) == SIGALRM) { warn("connect: connection attempt timed out"); } else if (!WIFEXITED(status)) { report_child_status("connect", status); @@ -583,7 +603,7 @@ static void *connchild_event(oop_source *lp, int fd, oop_event e, void *u) { /* child is still running apparently, report the socket problem */ if (rs < 0) syswarn("connect: read from child socket failed"); - else if (e == OOP_EXCEPTIONN) + else if (e == OOP_EXCEPTION) warn("connect: unexpected exception on child socket"); else warn("connect: unexpected EOF on child socket"); @@ -598,13 +618,14 @@ static void *connchild_event(oop_source *lp, int fd, oop_event e, void *u) { } CHK(level, SOL_SOCKET); CHK(type, SCM_RIGHTS); - CHK(len, CMSG_LEN(sizeof(conn-b>fd))); + CHK(len, CMSG_LEN(sizeof(conn->fd))); #undef CHK - if (CMSG_NXTHDR,&msg,h) { die("connect: child sent many cmsgs"); goto x; } + if (CMSG_NXTHDR(&msg,h)) { die("connect: child sent many cmsgs"); goto x; } memcpy(&conn->fd, CMSG_DATA(h), sizeof(conn->fd)); + int status; pid_t got= waitpid(connecting_child, &status, 0); if (got==-1) sysdie("connect: real wait for child"); assert(got == connecting_child); @@ -619,7 +640,7 @@ static void *connchild_event(oop_source *lp, int fd, oop_event e, void *u) { fatal("connect: child gave unexpected exit status %d", es); } - set nonblocking; + setnonblocking(conn->fd, 1); /* Phew! */ LIST_ADDHEAD(idle, conn); @@ -643,7 +664,7 @@ static void connect_start(void) { notice("starting connection attempt"); - r= socketpair(AF_UNIX, SOCK_STREAM, 0, connecting_sockets); + int r= socketpair(AF_UNIX, SOCK_STREAM, 0, connecting_sockets); if (r) { syswarn("connect: cannot create socketpair for child"); goto x; } connecting_child= xfork("connection"); @@ -685,11 +706,11 @@ static void connect_start(void) { fatal("connect: response to MODE STREAM is too long: %.100s...", remote_host, buf); } - l--; if (l>0 && buf[1-]=='\r') l--; + l--; if (l>0 && buf[l-1]=='\r') l--; buf[l]= 0; char *ep; int rcode= strtoul(buf,&ep,10); - if (ep != buf[3]) { + if (ep != &buf[3]) { sanitise_inplace(buf); fatal("connect: bad response to MODE STREAM: %.50s", buf); } @@ -727,7 +748,7 @@ static void connect_start(void) { if (r) sysdie("connect: close child socket in parent"); on_fd_read_except(connecting_sockets[0], connchild_event); - return OOP_CONTINUE; + return; x: connect_attempt_discard(); @@ -746,9 +767,9 @@ static void check_master_queue(void) { conn_assign_one_article(&working, &last_assigned); } else if (idle.head) { conn_assign_one_article(&idle, &last_assigned); - } else if (nconns < maxconns && queue.count >= max_queue_per_conn && - !connecting_child && !connect_delay) { - connect_delay= reconnect_delay_periods; + } else if (nconns < max_connections && queue.count >= max_queue_per_conn && + !connecting_child && !until_connect) { + until_connect= reconnect_delay_periods; connect_start(); } else { break; @@ -757,8 +778,7 @@ static void check_master_queue(void) { conn_check_work(last_assigned); } -static void conn_assign_one_article(LIST(Conn) *connlist, - Conn **last_assigned) { +static void conn_assign_one_article(ConnList *connlist, Conn **last_assigned) { Conn *conn= connlist->head; LIST_REMOVE(*connlist, conn); @@ -778,7 +798,7 @@ static int conn_total_queued_articles(Conn *conn) { return conn->sent.count + conn->queue.count; } -static LIST(Conn) *conn_determine_right_list(Conn *conn) { +static ConnList *conn_determine_right_list(Conn *conn) { int inqueue= conn_total_queued_articles(conn); assert(inqueue <= max_queue); if (inqueue == 0) return &idle; @@ -841,7 +861,7 @@ static void vconnfail(Conn *conn, const char *fmt, va_list al) { close(conn->fd); free(conn); - connect_delay= reconnect_delay_periods; + until_connect= reconnect_delay_periods; check_master_queue(); } @@ -2195,18 +2215,18 @@ static const char *debug_ipf_path(InputFile *ipf) { EVERY(period, {PERIOD_SECONDS,0}, { debug("PERIOD" - " sms=%s[%d] queue=%d connect_delay=%d" + " sms=%s[%d] queue=%d until_connect=%d" " input_files" DEBUGF_IPF(main) DEBUGF_IPF(old) DEBUGF_FMT(flushing) " conns idle=%d working=%d full=%d" " children connecting=%ld inndcomm_child" , - sms_names[sms], sm_period_counter, queue.count, connect_delay, + sms_names[sms], sm_period_counter, queue.count, until_connect, DEBUG_IPF(main), DEBUG_IPF(flushing), DEBUG_IPF(flushing), idle.count, working.count, full.count, (long)connecting_child, (long)inndcomm_child ); - if (connect_delay) connect_delay--; + if (until_connect) until_connect--; poll_backlog_file(); if (!backlog_input_file) close_defer(); /* want to start on a new backlog */