void CcnLAC_dtor(CcnLAC self) { if (self->pm != NULL) PollMgr_detach(self->pm, ccn_get_connection_fd(self->ccnh), &CcnLAC_initPollCb, self); if (self->nbs != NULL) NBS_pollDetach(self->nbs); ccn_destroy(&(self->ccnh)); if (self->ccnbor != NULL) CcnbOR_dtor(self->ccnbor); free(self); }
/** * Base loop for the background CCN task * * This is the main execution loop for the background task responsible for * interacting with the CCN network. It is from this point that many of the above methods are * called to work the inbound messages from ccnx as well as sending out the data messages. * * \param data the task context information setup by the parent sink element thread */ static void ccn_event_thread (void *data) { Gstccnxsink *me = (Gstccnxsink *) data; struct ccn_charbuf *filtName; struct ccn_charbuf *temp; int res = 0; GST_DEBUG ("CCNxSink event: *** event thread starting"); temp = ccn_charbuf_create (); filtName = ccn_charbuf_create (); /* A closure is what defines what to do when an inbound interest arrives */ if ((me->ccn_closure = calloc (1, sizeof (struct ccn_closure))) == NULL) { GST_ELEMENT_ERROR (me, RESOURCE, READ, (NULL), ("closure alloc failed")); return; } /* We setup the closure to contain the sink element context reference, and also tell it what function to call */ me->ccn_closure->data = me; me->ccn_closure->p = new_interests; me->timeouts = 0; ccn_charbuf_append (filtName, me->name->buf, me->name->length); /* This call will set up a handler for interests we expect to get from clients */ // hDump(DUMP_ADDR(filtName->buf), DUMP_SIZE(filtName->length)); ccn_set_interest_filter (me->ccn, filtName, me->ccn_closure); GST_DEBUG ("CCNxSink event: interest filter registered\n"); /* Some debugging information */ temp->length = 0; ccn_uri_append (temp, me->name->buf, me->name->length, TRUE); GST_DEBUG ("CCNxSink event: using uri: %s\n", ccn_charbuf_as_string (temp)); /* Now that the interest is registered, we loop around waiting for something to do */ /* We pass control to ccnx for a while so it can work with any incoming or outgoing data */ /* and then we check our fifo queue for work to do. That's about it! */ /* We check to see if any problems have caused our ccnd connection to fail, and we reconnect */ while (res >= 0) { GST_DEBUG ("CCNxSink event: *** looping"); res = ccn_run (me->ccn, 50); check_fifo (me); if (res < 0 && ccn_get_connection_fd (me->ccn) == -1) { GST_DEBUG ("CCNxSink event: need to reconnect..."); /* Try reconnecting, after a bit of delay */ msleep ((30 + (getpid () % 30)) * 1000); res = ccn_connect (me->ccn, ccndHost ()); } } GST_DEBUG ("CCNxSink event: *** event thread ending"); }
void CcnLAC_initPollCb(void* pself, PollMgrEvt evt, struct pollfd* fd) { CcnLAC self = (CcnLAC)pself; switch (evt) { case PollMgrEvt_prepare: CcnH_pollPrepare(self->ccnh, fd); break; case PollMgrEvt_result: CcnH_pollRun(self->ccnh, fd); break; case PollMgrEvt_error: self->error = true; PollMgr_detach(self->pm, ccn_get_connection_fd(self->ccnh), &CcnLAC_initPollCb, self); break; } }
int NdnMediaProcess::startThread() { struct ccn *h; /* Shut down any lingering session */ while (ndnState.ccn != NULL) { ndnState.active = 0; printf("waiting for old session to die\n"); } h = ccn_create(); if (ccn_connect(h, NULL) == -1) { ccn_perror(h, "Failed to contact ccnd"); ccn_destroy(&h); return (-1); } pthread_mutexattr_init(&ccn_attr); pthread_mutexattr_settype(&ccn_attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&ccn_mutex, &ccn_attr); ndnState.ccn = h; pfds[0].fd = ccn_get_connection_fd(ndnState.ccn); pfds[0].events = POLLIN; clock = new QTimer(this); connect(clock, SIGNAL(timeout()), this, SLOT(tick())); clock->start(PER_PACKET_LEN); if (! isRunning()) { fprintf(stderr, "Starting voice thread in media_pro\n"); ndnState.active = true; start(QThread::HighestPriority); #ifdef Q_OS_LINUX int policy; struct sched_param param; if (pthread_getschedparam(pthread_self(), &policy, ¶m) == 0) { if (policy == SCHED_OTHER) { policy = SCHED_FIFO; param.sched_priority = 1; pthread_setschedparam(pthread_self(), policy, ¶m); } } #endif } else fprintf(stderr, "what the hell\n"); return 0; }
/** * Base loop for the background CCN task * * This is the main execution loop for the background task responsible for * interacting with the CCN network. It is from this point that many of the above methods are * called to work the inbound messages from ccnx as well as sending new interest messages. * * \param data the task context information setup by the parent sink element thread */ static void ccn_event_thread (void *data) { Gstccnxsrc *src = (Gstccnxsrc *) data; struct ccn *ccn = src->ccn; int res = 0; GST_DEBUG ("*** event thread starting"); /* We pass control to ccnx for a while so it can work with any incoming or outgoing data */ /* We check to see if any problems have caused our ccnd connection to fail, and we reconnect */ while (res >= 0) { res = ccn_run (ccn, 1000); if (res < 0 && ccn_get_connection_fd (ccn) == -1) { /* Try reconnecting, after a bit of delay */ msleep ((30 + (getpid () % 30)) * 1000); res = ccn_connect (ccn, ccndHost ()); } } GST_DEBUG ("*** event thread ending"); }
static int ccnr_direct_client_refresh(struct ccn_schedule *sched, void *clienth, struct ccn_scheduled_event *ev, int flags) { struct ccnr_handle *ccnr = clienth; int microsec = 0; if ((flags & CCN_SCHEDULE_CANCEL) == 0 && ccnr->direct_client != NULL && ccnr->direct_client_refresh == ev) { microsec = ccn_process_scheduled_operations(ccnr->direct_client); // XXX - This is not really right, since an incoming request can cause us to need to reschedule this event. if CCNSHOULDLOG(ccnr, refresh, CCNL_FINEST) ccnr_msg(ccnr, "direct_client_refresh %d in %d usec", ccn_get_connection_fd(ccnr->direct_client), microsec); if (microsec > ev->evint) microsec = ev->evint; if (microsec == 0) microsec = CCN_INTEREST_LIFETIME_MICROSEC; }
void GroupManager::StartThread() { if (! isRunning()) { debug("Starting Userlist Handling thread"); bRunning = true; pfds[0].fd = ccn_get_connection_fd(ccn); pfds[0].events = POLLIN; start(QThread::HighestPriority); #ifdef Q_OS_LINUX // QThread::HighestPriority == Same as everything else... int policy; sched_param param; if (pthread_getschedparam(pthread_self(), &policy, ¶m) == 0) { if (policy == SCHED_OTHER) { policy = SCHED_FIFO; param.sched_priority = 1; pthread_setschedparam(pthread_self(), policy, ¶m); } } #endif } }
enum ccn_upcall_res CcnLAC_fetchFaceidCb(struct ccn_closure* selfp, enum ccn_upcall_kind kind, struct ccn_upcall_info* info) { CcnLAC self = (CcnLAC)selfp->data; switch (kind) { case CCN_UPCALL_FINAL: { free(selfp); return CCN_UPCALL_RESULT_OK; } case CCN_UPCALL_INTEREST_TIMED_OUT: { return CCN_UPCALL_RESULT_REEXPRESS; } case CCN_UPCALL_CONTENT_UNVERIFIED: case CCN_UPCALL_CONTENT_KEYMISSING: case CCN_UPCALL_CONTENT_RAW: case CCN_UPCALL_CONTENT: { struct ccn_forwarding_entry* fe = NULL; const unsigned char* fe_ccnb = NULL; size_t fe_ccnb_size = 0; int res = ccn_content_get_value(info->content_ccnb, info->pco->offset[CCN_PCO_E], info->pco, &fe_ccnb, &fe_ccnb_size); if (res == 0) fe = ccn_forwarding_entry_parse(fe_ccnb, fe_ccnb_size); if (fe != NULL) { self->faceid = fe->faceid; ccn_forwarding_entry_destroy(&fe); } else { self->error = true; } PollMgr_detach(self->pm, ccn_get_connection_fd(self->ccnh), &CcnLAC_initPollCb, self); void* emptyPDU = malloc(CCN_EMPTY_PDU_LENGTH); memcpy(emptyPDU, CCN_EMPTY_PDU, CCN_EMPTY_PDU_LENGTH); NBS_write(self->nbs, emptyPDU, 0, CCN_EMPTY_PDU_LENGTH, NULL); NBS_pollAttach(self->nbs, self->pm); return CCN_UPCALL_RESULT_OK; } default: { return CCN_UPCALL_RESULT_ERR; } } }
void CcnCC_pollDetach(CcnCC self, PollMgr pm) { PollMgr_detach(pm, ccn_get_connection_fd(self->ccnh), &CcnCC_pollCb, self); }
/** * Create a new ccnr instance * @param progname - name of program binary, used for locating helpers * @param logger - logger function * @param loggerdata - data to pass to logger function */ PUBLIC struct ccnr_handle * r_init_create(const char *progname, ccnr_logger logger, void *loggerdata) { char *sockname = NULL; const char *portstr = NULL; const char *listen_on = NULL; const char *d = NULL; struct ccnr_handle *h = NULL; struct hashtb_param param = {0}; struct ccn_charbuf *config = NULL; int res; h = calloc(1, sizeof(*h)); if (h == NULL) return(h); h->notify_after = 0; //CCNR_MAX_ACCESSION; h->logger = logger; h->loggerdata = loggerdata; h->logpid = (int)getpid(); h->progname = progname; h->debug = -1; config = r_init_read_config(h); if (config == NULL) goto Bail; r_init_parse_config(h, config, 0); /* silent pass to pick up CCNR_DEBUG */ h->debug = 1; /* so that we see any complaints */ h->debug = r_init_debug_getenv(h, "CCNR_DEBUG"); res = r_init_parse_config(h, config, 1); if (res < 0) { h->running = -1; goto Bail; } r_init_parse_config(h, config, 2); sockname = r_net_get_local_sockname(); h->skiplinks = ccn_indexbuf_create(); h->face_limit = 10; /* soft limit */ h->fdholder_by_fd = calloc(h->face_limit, sizeof(h->fdholder_by_fd[0])); param.finalize_data = h; param.finalize = &r_fwd_finalize_nameprefix; h->nameprefix_tab = hashtb_create(sizeof(struct nameprefix_entry), ¶m); param.finalize = 0; // PRUNED &r_fwd_finalize_propagating; h->propagating_tab = hashtb_create(sizeof(struct propagating_entry), ¶m); param.finalize = &r_proto_finalize_enum_state; h->enum_state_tab = hashtb_create(sizeof(struct enum_state), ¶m); h->min_stale = ~0; h->max_stale = 0; h->unsol = ccn_indexbuf_create(); h->ticktock.descr[0] = 'C'; h->ticktock.micros_per_base = 1000000; h->ticktock.gettime = &r_util_gettime; h->ticktock.data = h; h->sched = ccn_schedule_create(h, &h->ticktock); h->starttime = h->sec; h->starttime_usec = h->usec; h->oldformatcontentgrumble = 1; h->oldformatinterestgrumble = 1; h->cob_limit = 4201; h->start_write_scope_limit = r_init_confval(h, "CCNR_START_WRITE_SCOPE_LIMIT", 0, 3, 3); h->debug = 1; /* so that we see any complaints */ h->debug = r_init_debug_getenv(h, "CCNR_DEBUG"); h->syncdebug = r_init_debug_getenv(h, "CCNS_DEBUG"); portstr = getenv("CCNR_STATUS_PORT"); if (portstr == NULL || portstr[0] == 0 || strlen(portstr) > 10) portstr = ""; h->portstr = portstr; ccnr_msg(h, "CCNR_DEBUG=%d CCNR_DIRECTORY=%s CCNR_STATUS_PORT=%s", h->debug, h->directory, h->portstr); listen_on = getenv("CCNR_LISTEN_ON"); if (listen_on != NULL && listen_on[0] != 0) ccnr_msg(h, "CCNR_LISTEN_ON=%s", listen_on); if (ccnr_init_repo_keystore(h, NULL) < 0) { h->running = -1; goto Bail; } r_util_reseed(h); r_store_init(h); if (h->running == -1) goto Bail; while (h->active_in_fd >= 0) { r_dispatch_process_input(h, h->active_in_fd); r_store_trim(h, h->cob_limit); ccn_schedule_run(h->sched); } ccnr_msg(h, "Repository file is indexed"); if (h->face0 == NULL) { struct fdholder *fdholder; fdholder = calloc(1, sizeof(*fdholder)); if (dup2(open("/dev/null", O_RDONLY), 0) == -1) ccnr_msg(h, "stdin: %s", strerror(errno)); fdholder->filedesc = 0; fdholder->flags = (CCNR_FACE_GG | CCNR_FACE_NORECV); r_io_enroll_face(h, fdholder); } ccnr_direct_client_start(h); d = getenv("CCNR_SKIP_VERIFY"); #if (CCN_API_VERSION >= 4004) if (d != NULL && strcmp(d, "1") == 0) { ccnr_msg(h, "CCNR_SKIP_VERIFY=%s", d); ccn_defer_verification(h->direct_client, 1); } #endif if (ccn_connect(h->direct_client, NULL) != -1) { int af = 0; int bufsize; int flags; int fd; struct fdholder *fdholder; fd = ccn_get_connection_fd(h->direct_client); // Play a dirty trick here - if this wins, we can fix it right in the c lib later on... af = try_tcp_instead(fd); flags = CCNR_FACE_CCND; if (af == AF_INET) flags |= CCNR_FACE_INET; else if (af == AF_INET6) flags |= CCNR_FACE_INET6; else flags |= CCNR_FACE_LOCAL; fdholder = r_io_record_fd(h, fd, "CCND", 5, flags); if (fdholder == NULL) abort(); ccnr_uri_listen(h, h->direct_client, "ccnx:/%C1.M.S.localhost/%C1.M.SRV/repository", &ccnr_answer_req, OP_SERVICE); ccnr_uri_listen(h, h->direct_client, "ccnx:/%C1.M.S.neighborhood/%C1.M.SRV/repository", &ccnr_answer_req, OP_SERVICE); bufsize = r_init_confval(h, "CCNR_MIN_SEND_BUFSIZE", 1, 2097152, 16384); establish_min_send_bufsize(h, fd, bufsize); } else ccn_disconnect(h->direct_client); // Apparently ccn_connect error case needs work. if (1 == r_init_confval(h, "CCNS_ENABLE", 0, 1, 1)) { h->sync_plumbing = calloc(1, sizeof(struct sync_plumbing)); h->sync_plumbing->ccn = h->direct_client; h->sync_plumbing->sched = h->sched; h->sync_plumbing->client_methods = &sync_client_methods; h->sync_plumbing->client_data = h; h->sync_base = SyncNewBaseForActions(h->sync_plumbing); } if (-1 == load_policy(h)) goto Bail; r_net_listen_on(h, listen_on); ccnr_internal_client_start(h); r_proto_init(h); r_proto_activate_policy(h, h->parsed_policy); if (merge_files(h) == -1) r_init_fail(h, __LINE__, "Unable to merge additional repository data files.", errno); if (h->running == -1) goto Bail; if (h->sync_plumbing) { // Start sync running // returns < 0 if a failure occurred // returns 0 if the name updates should fully restart // returns > 0 if the name updates should restart at last fence res = h->sync_plumbing->sync_methods->sync_start(h->sync_plumbing, NULL); if (res < 0) { r_init_fail(h, __LINE__, "starting sync", res); abort(); } else if (res > 0) { // XXX: need to work out details of starting from last fence. // By examination of code, SyncActions won't take this path } } Bail: if (sockname) free(sockname); sockname = NULL; ccn_charbuf_destroy(&config); if (h->running == -1) r_init_destroy(&h); return(h); }