All pastes #954913 Raw Edit

Miscellany

public text v1 · immutable
#954913 ·published 2008-03-24 05:28 UTC
rendered paste body
listen_ecb.do_read = do_accept;
listen_ecb.do_write = NULL;
listen_ecb.bufs = NULL;
int kq = kqueue();
ke_change (sock, EVFILT_READ, EV_ADD | EV_ENABLE, &listen_ecb);
}

static void ke_change (int const ident,int const filter, int const flags, void *const udata){
    enum { initial_alloc = 1024 };
    struct kevent *kep;
    if (!ke_vec_alloc){
        ke_vec_alloc=initial_alloc;
        ke_vec=(struct kevent*)malloc(ke_vec_alloc*sizeof (struct kevent));
    }else if (ke_vec_used == ke_vec_alloc){
        ke_vec_alloc<<=1;
        ke_vec=(struct kevent*)realloc(ke_vec, ke_vec_alloc*sizeof(struct kevent));
    }
    kep = &ke_vec[ke_vec_used++];
    kep->ident = ident;
    kep->filter = filter;
    kep->flags = flags;
    log_printf("ke_change socket=%d filter=%s flags=0x%04x (%s%s%s%s%s%s%s%s), ", kep->ident, (kep->filter==EVFILT_READ?"EVFILT_READ":"EVFILT_WRITE"), flags,
            (flags & EV_EOF) ? "EV_EOF" : "",
            (flags & EV_ERROR)  ? ((flags & (~(EV_ERROR - 1) & ~EV_ERROR)) ? " | EV_ERROR" : "EV_ERROR") : "",
            (flags & EV_ADD)    ? ((flags & (EV_SYSFLAGS | (EV_ADD - 1))) ? " | EV_ADD" : "EV_ADD") : "",
            (flags & EV_DELETE)   ? ((flags & (EV_SYSFLAGS | (EV_DELETE - 1))) ? " | EV_DELETE" : "EV_DELETE") : "",
            (flags & EV_ENABLE)   ? ((flags & (EV_SYSFLAGS | (EV_ENABLE - 1))) ? " | EV_ENABLE" : "EV_ENABLE") : "",
            (flags & EV_DISABLE)  ? ((flags & (EV_SYSFLAGS | (EV_DISABLE - 1))) ? " | EV_DISABLE" : "EV_DISABLE") : "",
            (flags & EV_ONESHOT)  ? ((flags & (EV_SYSFLAGS | (EV_ONESHOT - 1))) ? " | EV_ONESHOT" : "EV_ONESHOT") : "",
            (flags & EV_CLEAR)  ? ((flags & (EV_SYSFLAGS | (EV_CLEAR - 1))) ? " | EV_CLEAR" : "EV_CLEAR") : "" );
    kep->fflags = 0;
    kep->data = 0;
    kep->udata = udata;
}


void unistall_connect(ecb *ecbp){
    ke_change(ecbp->ident, EVFILT_READ, EV_DELETE, NULL);
    ke_change(ecbp->ident, EVFILT_WRITE, EV_DELETE, NULL);
//    ke_change(ecbp->ident, EVFILT_WRITE, EV_CLEAR, (void*)1);
//    ke_change(ecbp->ident, EVFILT_READ, EV_CLEAR, (void*)1);
    close(ecbp->ident);
    free_msgs(ecbp);
    free(ecbp->bufs);
    free(ecbp->bufsiz);
    XML_ParserFree(ecbp->parser);
    free(ecbp);
}


static void event_loop (int const kq){
  while(1){
        int n;
        struct kevent const *kep;
        ke_vec_ghost = ke_vec_used;
        log_printf("kevent() ke_vec_used = %d",ke_vec_used);
        n = kevent (kq, ke_vec, ke_vec_used, ke_vec, ke_vec_alloc, NULL);
        log_printf("%d events recieved :)",n);
        ke_vec_used = 0;
        if (n == -1)
            log_printf("Error in kevent(): %s", strerror (errno));
        if (n == 0)
            log_printf("No events received!");
        for (kep = ke_vec; kep < &ke_vec[n]; kep++){
            if(!kep->udata) continue; //костылик
            log_printf("event socket %d: %s",kep->ident,(kep->filter==EVFILT_READ?"EVFILT_READ":"!EVFILT_READ"));
            ecb const *const ecbp = (ecb *) kep->udata;
            if (kep->filter == EVFILT_READ)
                (*ecbp->do_read) (kep);
            else
                (*ecbp->do_write) (kep);
        }
    }
}

static void do_read (register struct kevent const *const kep){
    enum { bufsize = 1024 };
    char buf[bufsize];
    int n;
    ecb *ecbp = (ecb *) kep->udata;
    if ((n = read (kep->ident, buf, bufsize)) == -1){
        log_printf("Error reading socket: %s", strerror (errno));
        unistall_connect(ecbp);
        return;
    }else if(n == 0){
        log_printf("disconnect %s",inet_ntoa(ecbp->sin.sin_addr));
        unistall_connect(ecbp);
        return;
    }
    if (XML_Parse(ecbp->parser, buf, n, 0) == XML_STATUS_ERROR) {
        char *errormsg = calloc(1024, sizeof(char));
        sprintf(errormsg, "<error type=\"protocol\" line=\"%lu\">%s</error>\n", XML_GetCurrentLineNumber(ecbp->parser),XML_ErrorString(XML_GetErrorCode(ecbp->parser)));
        add_msg(ecbp,errormsg);
        ecbp->on_error=1;
        log_printf("disconnect %s on protocol error",inet_ntoa(ecbp->sin.sin_addr));
    }
}

static void do_write(register struct kevent const *const kep){
    int n,i;
    ecb *ecbp = (ecb*) kep->udata;
    for(i=0;i<ecbp->bufnum;i++){
        n = write(kep->ident, ecbp->bufs[i], ecbp->bufsiz[i]);
        if (n == -1){
            log_printf("Error writing socket: %s", strerror (errno));
            unistall_connect(ecbp);
            return;
        }
    }
    if(ecbp->on_error){
        unistall_connect(ecbp);
        return;
    }
    free_msgs(ecbp);
    ke_change(ecbp->ident, EVFILT_WRITE, EV_DISABLE, ecbp);
}