void remove_vnode_from_name_tree(struct fuse *f, struct fuse_vnode *vn) { struct fuse_vn_head *vn_head; struct fuse_vnode *v; struct fuse_vnode *lastv; vn_head = dict_get(&f->name_tree, vn->path); if (vn_head == NULL) return; lastv = NULL; SIMPLEQ_FOREACH(v, vn_head, node) { if (v->parent == vn->parent) break; lastv = v; } if (v == NULL) return; /* if we found the vnode remove it */ if (v == SIMPLEQ_FIRST(vn_head)) SIMPLEQ_REMOVE_HEAD(vn_head, node); else SIMPLEQ_REMOVE_AFTER(vn_head, lastv, node); /* if the queue is empty we need to remove it from the dict */ if (SIMPLEQ_EMPTY(vn_head)) { vn_head = dict_pop(&f->name_tree, vn->path); free(vn_head); } }
void *datalogger_thread(void *queue_ptr) { struct da_entry *dae = NULL; struct s_datalog_entry *dle = NULL; char timestamp[16]; log_debug("starting datalogger thread"); while (1) { pthread_mutex_lock(&da_mutex); pthread_cond_wait(&da_cond, &da_mutex); if (!(SIMPLEQ_EMPTY(&da_head))) { dae = SIMPLEQ_FIRST(&da_head); SIMPLEQ_REMOVE_HEAD(&da_head, da_entries); } pthread_mutex_unlock(&da_mutex); if (dae != NULL) { if (!(dle = (struct s_datalog_entry *)malloc(sizeof(struct s_datalog_entry)))) { log_error("datalogger_thread: malloc failed"); } struct tm *tm_now = localtime(&dae->timestamp); strftime(timestamp, sizeof(timestamp), "%Y%m%d%H%M%S", tm_now); (void)snprintf(dle->line, sizeof(dle->line), "%s,%d,%.02f,%.02f,%.02f,%.02f,%.02f,%d,%.02f,%.02f\n", timestamp, dae->values->host_id, dae->values->temperature, dae->values->pressure, dae->values->humidity, dae->values->light, dae->values->wind_speed, (unsigned int)dae->values->wind_direction, dae->values->wind_chill, dae->values->rainfall); datalogger_write(dle); free(dae); free(dle); } } return 0; }
static void network_notifier(RECOVERY_STATUS status, int error, const char *msg) { int len = msg ? strlen(msg) : 0; struct msg_elem *newmsg = (struct msg_elem *)calloc(1, sizeof(*newmsg) + len + 1); struct msg_elem *oldmsg; if (!newmsg) return; pthread_mutex_lock(&msglock); nrmsgs++; if (nrmsgs > NUM_CACHED_MESSAGES) { oldmsg = SIMPLEQ_FIRST(¬ifymsgs); SIMPLEQ_REMOVE_HEAD(¬ifymsgs, next); free(oldmsg); nrmsgs--; } newmsg->msg = (char *)newmsg + sizeof(struct msg_elem); newmsg->status = status; newmsg->error = error; if (msg) { strncpy(newmsg->msg, msg, len); clean_msg(newmsg->msg, '\t'); clean_msg(newmsg->msg, '\n'); clean_msg(newmsg->msg, '\r'); } SIMPLEQ_INSERT_TAIL(¬ifymsgs, newmsg, next); pthread_mutex_unlock(&msglock); }
static void out_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct umidi_endpoint *ep = (struct umidi_endpoint *)priv; struct umidi_softc *sc = ep->sc; struct umidi_jack *j; unsigned pending; if (usbd_is_dying(sc->sc_udev)) return; ep->used = 0; ep->busy = 0; for (pending = ep->pending; pending > 0; pending--) { j = SIMPLEQ_FIRST(&ep->intrq); #ifdef DIAGNOSTIC if (j == NULL) { printf("umidi: missing intr entry\n"); break; } #endif SIMPLEQ_REMOVE_HEAD(&ep->intrq, intrq_entry); ep->pending--; j->intr = 0; mtx_enter(&audio_lock); if (j->opened && j->u.out.intr) (*j->u.out.intr)(j->arg); mtx_leave(&audio_lock); } }
static void ucomstart(struct tty *tp) { struct ucom_softc *sc = device_lookup_private(&ucom_cd, UCOMUNIT(tp->t_dev)); struct ucom_buffer *ub; int s; u_char *data; int cnt; if (sc->sc_dying) return; s = spltty(); if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) { DPRINTFN(4,("ucomstart: no go, state=0x%x\n", tp->t_state)); goto out; } if (sc->sc_tx_stopped) goto out; if (!ttypull(tp)) goto out; /* Grab the first contiguous region of buffer space. */ data = tp->t_outq.c_cf; cnt = ndqb(&tp->t_outq, 0); if (cnt == 0) { DPRINTF(("ucomstart: cnt==0\n")); goto out; } ub = SIMPLEQ_FIRST(&sc->sc_obuff_free); KASSERT(ub != NULL); SIMPLEQ_REMOVE_HEAD(&sc->sc_obuff_free, ub_link); if (SIMPLEQ_FIRST(&sc->sc_obuff_free) == NULL) SET(tp->t_state, TS_BUSY); if (cnt > sc->sc_obufsize) cnt = sc->sc_obufsize; if (sc->sc_methods->ucom_write != NULL) sc->sc_methods->ucom_write(sc->sc_parent, sc->sc_portno, ub->ub_data, data, &cnt); else memcpy(ub->ub_data, data, cnt); ub->ub_len = cnt; ub->ub_index = 0; SIMPLEQ_INSERT_TAIL(&sc->sc_obuff_full, ub, ub_link); softint_schedule(sc->sc_si); out: splx(s); }
/* * Initialize the transmit descriptors. */ static void rtk_list_tx_init(struct rtk_softc *sc) { struct rtk_tx_desc *txd; int i; while ((txd = SIMPLEQ_FIRST(&sc->rtk_tx_dirty)) != NULL) SIMPLEQ_REMOVE_HEAD(&sc->rtk_tx_dirty, txd_q); while ((txd = SIMPLEQ_FIRST(&sc->rtk_tx_free)) != NULL) SIMPLEQ_REMOVE_HEAD(&sc->rtk_tx_free, txd_q); for (i = 0; i < RTK_TX_LIST_CNT; i++) { txd = &sc->rtk_tx_descs[i]; CSR_WRITE_4(sc, txd->txd_txaddr, 0); SIMPLEQ_INSERT_TAIL(&sc->rtk_tx_free, txd, txd_q); } }
static int ld_ataraid_start_span(struct ld_softc *ld, struct buf *bp) { struct ld_ataraid_softc *sc = (void *) ld; struct ataraid_array_info *aai = sc->sc_aai; struct ataraid_disk_info *adi; struct cbuf *cbp; char *addr; daddr_t bn; long bcount, rcount; u_int comp; /* Allocate component buffers. */ addr = bp->b_data; /* Find the first component. */ comp = 0; adi = &aai->aai_disks[comp]; bn = bp->b_rawblkno; while (bn >= adi->adi_compsize) { bn -= adi->adi_compsize; adi = &aai->aai_disks[++comp]; } bp->b_resid = bp->b_bcount; for (bcount = bp->b_bcount; bcount > 0; bcount -= rcount) { rcount = bp->b_bcount; if ((adi->adi_compsize - bn) < btodb(rcount)) rcount = dbtob(adi->adi_compsize - bn); cbp = ld_ataraid_make_cbuf(sc, bp, comp, bn, addr, rcount); if (cbp == NULL) { /* Free the already allocated component buffers. */ while ((cbp = SIMPLEQ_FIRST(&sc->sc_cbufq)) != NULL) { SIMPLEQ_REMOVE_HEAD(&sc->sc_cbufq, cb_q); CBUF_PUT(cbp); } return EAGAIN; } /* * For a span, we always know we advance to the next disk, * and always start at offset 0 on that disk. */ adi = &aai->aai_disks[++comp]; bn = 0; SIMPLEQ_INSERT_TAIL(&sc->sc_cbufq, cbp, cb_q); addr += rcount; } /* Now fire off the requests. */ softint_schedule(sc->sc_sih_cookie); return 0; }
void kthread_run_deferred_queue(void) { struct kthread_q *kq; while ((kq = SIMPLEQ_FIRST(&kthread_q)) != NULL) { SIMPLEQ_REMOVE_HEAD(&kthread_q, kq, kq_q); (*kq->kq_func)(kq->kq_arg); free(kq, M_TEMP); } }
void fsd_equeue_fini(void) { struct fsd_equeue_entry *entry; while ((entry = SIMPLEQ_FIRST(&fsd_equeue_head)) != NULL) { fsd_evt_fini(entry->evt); SIMPLEQ_REMOVE_HEAD(&fsd_equeue_head, entries); } return; }
static void xbdresume(void) { struct xbdreq *pxr, *xr; struct xbd_softc *xs; struct buf *bp; while ((pxr = SIMPLEQ_FIRST(&xbdr_suspended)) != NULL) { DPRINTF(XBDB_IO, ("xbdstart: resuming xbdreq %p for bp %p\n", pxr, pxr->xr_bp)); bp = pxr->xr_bp; xs = getxbd_softc(bp->b_dev); if (xs == NULL || xs->sc_shutdown) { bp->b_flags |= B_ERROR; bp->b_error = EIO; } if (bp->b_flags & B_ERROR) { pxr->xr_bdone -= pxr->xr_bqueue; pxr->xr_bqueue = 0; if (pxr->xr_bdone == 0) { bp->b_resid = bp->b_bcount; if (pxr->xr_aligned) unmap_align(pxr); PUT_XBDREQ(pxr); if (xs) { disk_unbusy(&xs->sc_dksc.sc_dkdev, (bp->b_bcount - bp->b_resid), (bp->b_flags & B_READ)); #if NRND > 0 rnd_add_uint32(&xs->rnd_source, bp->b_blkno); #endif } biodone(bp); } continue; } while (__predict_true(pxr->xr_bqueue > 0)) { GET_XBDREQ(xr); if (__predict_false(xr == NULL)) goto out; xr->xr_parent = pxr; fill_ring(xr); } DPRINTF(XBDB_IO, ("xbdstart: resumed xbdreq %p for bp %p\n", pxr, bp)); SIMPLEQ_REMOVE_HEAD(&xbdr_suspended, xr_suspended); } out: return; }
/* * When a routine that uses resources is finished, the next device * in queue for map registers etc is called. If it succeeds to get * resources, call next, and next, and next... * This routine must be called at splvm. */ void uba_done(struct uba_softc *uh) { struct uba_unit *uu; while ((uu = SIMPLEQ_FIRST(&uh->uh_resq))) { SIMPLEQ_REMOVE_HEAD(&uh->uh_resq, uu_resq); if ((*uu->uu_ready)(uu) == 0) { SIMPLEQ_INSERT_HEAD(&uh->uh_resq, uu, uu_resq); break; } } }
fsd_evt_t * fsd_equeue_pop(void) { struct fsd_equeue_entry *entry; fsd_evt_t *evt = NULL; if ((entry = SIMPLEQ_FIRST(&fsd_equeue_head)) != NULL) { evt = entry->evt; SIMPLEQ_REMOVE_HEAD(&fsd_equeue_head, entries); } return (evt); }
/* * Undo the changes done above. * Such a function is necessary since we need a full-blown pcmcia world * set up in order to do the device probe, but if we don't match the card, * leaving this state will cause trouble during other probes. */ void cfxga_remove_function(struct pcmcia_function *pf) { struct pcmcia_config_entry *cfe; /* we are the first and only entry... */ cfe = SIMPLEQ_FIRST(&pf->cfe_head); SIMPLEQ_REMOVE_HEAD(&pf->cfe_head, cfe_list); free(cfe, M_DEVBUF); /* And we're a figment of the kernel's imagination again. */ pf->pf_flags |= PFF_FAKE; }
void free_rdomains(struct rdomain_head *rdomains) { struct rdomain *rd; while ((rd = SIMPLEQ_FIRST(rdomains)) != NULL) { SIMPLEQ_REMOVE_HEAD(rdomains, entry); filterset_free(&rd->export); filterset_free(&rd->import); free_networks(&rd->net_l); free(rd); } }
static void cleanum_msg_list(void) { struct msg_elem *notification; pthread_mutex_lock(&msglock); while (!SIMPLEQ_EMPTY(¬ifymsgs)) { notification = SIMPLEQ_FIRST(¬ifymsgs); SIMPLEQ_REMOVE_HEAD(¬ifymsgs, next); free(notification); } nrmsgs = 0; pthread_mutex_unlock(&msglock); }
void *aggregate_thread(void *queue_ptr) { struct pa_entry *pae = NULL; struct da_entry *dae = NULL; struct ga_entry *gae = NULL; struct s_aggregate *aggregates = NULL; // char buf[255]; log_debug("starting aggregate thread"); while (1) { pthread_mutex_lock(&pa_mutex); pthread_cond_wait(&pa_cond, &pa_mutex); pae = SIMPLEQ_FIRST(&pa_head); SIMPLEQ_REMOVE_HEAD(&pa_head, pa_entries); pthread_mutex_unlock(&pa_mutex); update_aggregates(pae->packet); free(pae); if (has_aggregates()) { aggregates = get_aggregates(); if (!(dae = (struct da_entry *)malloc(sizeof(struct da_entry)))) { log_error("aggregate_thread: dae: malloc failed"); } dae->values = aggregates; dae->timestamp = time(NULL); pthread_mutex_lock(&da_mutex); SIMPLEQ_INSERT_TAIL(&da_head, dae, da_entries); pthread_cond_signal(&da_cond); pthread_mutex_unlock(&da_mutex); if (!(gae = (struct ga_entry *)malloc(sizeof(struct ga_entry)))) { log_error("aggregate_thread: gae: malloc failed"); } gae->values = aggregates; gae->timestamp = dae->timestamp; pthread_mutex_lock(&ga_mutex); SIMPLEQ_INSERT_TAIL(&ga_head, gae, ga_entries); pthread_cond_signal(&ga_cond); pthread_mutex_unlock(&ga_mutex); } } return 0; }
static void ld_ataraid_start_vstrategy(void *arg) { struct ld_ataraid_softc *sc = arg; struct cbuf *cbp; while ((cbp = SIMPLEQ_FIRST(&sc->sc_cbufq)) != NULL) { SIMPLEQ_REMOVE_HEAD(&sc->sc_cbufq, cb_q); if ((cbp->cb_buf.b_flags & B_READ) == 0) { mutex_enter(cbp->cb_buf.b_vp->v_interlock); cbp->cb_buf.b_vp->v_numoutput++; mutex_exit(cbp->cb_buf.b_vp->v_interlock); } VOP_STRATEGY(cbp->cb_buf.b_vp, &cbp->cb_buf); } }
void *graphite_thread(void *queue_ptr) { struct ga_entry *gae = NULL; struct s_graphite_entry *entry = NULL; // char buffer[1024]; char timestamp[11]; log_debug("starting graphite thread"); while (1) { pthread_mutex_lock(&ga_mutex); pthread_cond_wait(&ga_cond, &ga_mutex); if (!(SIMPLEQ_EMPTY(&ga_head))) { gae = SIMPLEQ_FIRST(&ga_head); SIMPLEQ_REMOVE_HEAD(&ga_head, ga_entries); } pthread_mutex_unlock(&ga_mutex); if (gae != NULL) { struct tm *tm_now = localtime(&gae->timestamp); strftime(timestamp, sizeof(timestamp), "%s", tm_now); if (!(entry = (struct s_graphite_entry *)malloc(sizeof(struct s_graphite_entry)))) { log_error("graphite_thread: malloc failed"); } entry->host_id = gae->values->host_id; entry->temperature = gae->values->temperature; entry->pressure = gae->values->pressure; entry->c_pressure = gae->values->c_pressure; entry->humidity = gae->values->humidity; entry->light = gae->values->light; entry->wind_speed = gae->values->wind_speed; entry->wind_direction = gae->values->wind_direction; entry->wind_chill = gae->values->wind_chill; entry->rainfall = gae->values->rainfall; entry->timestamp = timestamp; graphite_write(entry); free(entry); free(gae); } } return 0; }
/* * If a CCB is specified, enqueue it. Pull CCBs off the software queue in * the order that they were enqueued and try to submit their command blocks * to the controller for execution. */ void twe_ccb_enqueue(struct twe_softc *sc, struct twe_ccb *ccb) { int s; s = splbio(); if (ccb != NULL) SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_queue, ccb, ccb_chain.simpleq); while ((ccb = SIMPLEQ_FIRST(&sc->sc_ccb_queue)) != NULL) { if (twe_ccb_submit(sc, ccb)) break; SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_queue, ccb_chain.simpleq); } splx(s); }
//Calls up on the semaphore //purpose is to release the lock void up( semaphore_t* sem ){ //mutual exclusion pthread_mutex_lock(&sem->mutex); if(sem->wakeupCount > 0 ){ //This is where I want to dequeue from the SimpleQ SIMPLEQ_REMOVE_HEAD( &sem->conditionalQueue, (np = SIMPLEQ_FIRST(&sem->conditionalQueue)), next ); pthread_cond_signal(&np->condition); free(np); --sem->wakeupCount; } ++sem->count; pthread_mutex_unlock(&sem->mutex); }
static void ucom_write_status(struct ucom_softc *sc, struct ucom_buffer *ub, usbd_status err) { struct tty *tp = sc->sc_tty; uint32_t cc = ub->ub_len; switch (err) { case USBD_IN_PROGRESS: ub->ub_index = ub->ub_len; break; case USBD_STALLED: ub->ub_index = 0; softint_schedule(sc->sc_si); break; case USBD_NORMAL_COMPLETION: usbd_get_xfer_status(ub->ub_xfer, NULL, NULL, &cc, NULL); #if defined(__NetBSD__) && NRND > 0 rnd_add_uint32(&sc->sc_rndsource, cc); #endif /*FALLTHROUGH*/ default: SIMPLEQ_REMOVE_HEAD(&sc->sc_obuff_full, ub_link); SIMPLEQ_INSERT_TAIL(&sc->sc_obuff_free, ub, ub_link); cc -= sc->sc_opkthdrlen; CLR(tp->t_state, TS_BUSY); if (ISSET(tp->t_state, TS_FLUSH)) CLR(tp->t_state, TS_FLUSH); else ndflush(&tp->t_outq, cc); if (err != USBD_CANCELLED && err != USBD_IOERROR && !sc->sc_dying) { if ((ub = SIMPLEQ_FIRST(&sc->sc_obuff_full)) != NULL) ucom_submit_write(sc, ub); (*tp->t_linesw->l_start)(tp); } break; } }
/* * Enqueue the specified command (if any) and attempt to start all enqueued * commands. */ static int cac_ccb_start(struct cac_softc *sc, struct cac_ccb *ccb) { KASSERT(mutex_owned(&sc->sc_mutex)); if (ccb != NULL) SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_queue, ccb, ccb_chain); while ((ccb = SIMPLEQ_FIRST(&sc->sc_ccb_queue)) != NULL) { if ((*sc->sc_cl.cl_fifo_full)(sc)) return (EAGAIN); SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_queue, ccb_chain); #ifdef DIAGNOSTIC ccb->ccb_flags |= CAC_CCB_ACTIVE; #endif (*sc->sc_cl.cl_submit)(sc, ccb); } return (0); }
/* * Create a link socket. */ sockid_t lnksock_socket(int type, int protocol, struct sock ** sockp, const struct sockevent_ops ** ops) { struct lnksock *lnk; if (type != SOCK_DGRAM) return EPROTOTYPE; if (protocol != 0) return EPROTONOSUPPORT; if (SIMPLEQ_EMPTY(&lnk_freelist)) return ENOBUFS; lnk = SIMPLEQ_FIRST(&lnk_freelist); SIMPLEQ_REMOVE_HEAD(&lnk_freelist, lnk_next); *sockp = &lnk->lnk_sock; *ops = &lnksock_ops; return SOCKID_LNK | (sockid_t)(lnk - lnk_array); }
/* * Allocate a CCB. */ static struct cac_ccb * cac_ccb_alloc(struct cac_softc *sc, int nosleep) { struct cac_ccb *ccb; mutex_enter(&sc->sc_mutex); for (;;) { if ((ccb = SIMPLEQ_FIRST(&sc->sc_ccb_free)) != NULL) { SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_free, ccb_chain); break; } if (nosleep) { ccb = NULL; break; } cv_wait(&sc->sc_ccb_cv, &sc->sc_mutex); } mutex_exit(&sc->sc_mutex); return (ccb); }
static void ucom_read_complete(struct ucom_softc *sc) { int (*rint)(int, struct tty *); struct ucom_buffer *ub; struct tty *tp; int s; tp = sc->sc_tty; rint = tp->t_linesw->l_rint; ub = SIMPLEQ_FIRST(&sc->sc_ibuff_full); while (ub != NULL && !sc->sc_rx_stopped) { s = spltty(); while (ub->ub_index < ub->ub_len && !sc->sc_rx_stopped) { /* Give characters to tty layer. */ if ((*rint)(ub->ub_data[ub->ub_index], tp) == -1) { /* Overflow: drop remainder */ ub->ub_index = ub->ub_len; } else ub->ub_index++; } splx(s); if (ub->ub_index == ub->ub_len) { SIMPLEQ_REMOVE_HEAD(&sc->sc_ibuff_full, ub_link); ucomsubmitread(sc, ub); ub = SIMPLEQ_FIRST(&sc->sc_ibuff_full); } } sc->sc_rx_unblock = (ub != NULL); }
// Called by ms_scan either in a thread or synchronously static void *do_scan(void *userdata) { MediaScan *s = ((thread_data_type *)userdata)->s; int i; struct dirq *dir_head = (struct dirq *)s->_dirq; struct dirq_entry *dir_entry = NULL; struct fileq *file_head = NULL; struct fileq_entry *file_entry = NULL; char tmp_full_path[MAX_PATH_STR_LEN]; // Initialize the cache database if (!init_bdb(s)) { MediaScanError *e = error_create("", MS_ERROR_CACHE, "Unable to initialize libmediascan cache"); send_error(s, e); goto out; } if (s->flags & MS_CLEARDB) { reset_bdb(s); } if (s->progress == NULL) { MediaScanError *e = error_create("", MS_ERROR_TYPE_INVALID_PARAMS, "Progress object not created"); send_error(s, e); goto out; } // Build a list of all directories and paths // We do this first so we can present an accurate scan eta later progress_start_phase(s->progress, "Discovering"); for (i = 0; i < s->npaths; i++) { LOG_INFO("Scanning %s\n", s->paths[i]); recurse_dir(s, s->paths[i], 0); } // Scan all files found progress_start_phase(s->progress, "Scanning"); while (!SIMPLEQ_EMPTY(dir_head)) { dir_entry = SIMPLEQ_FIRST(dir_head); file_head = dir_entry->files; while (!SIMPLEQ_EMPTY(file_head)) { // check if the scan has been aborted if (s->_want_abort) { LOG_DEBUG("Aborting scan\n"); goto aborted; } file_entry = SIMPLEQ_FIRST(file_head); // Construct full path strcpy(tmp_full_path, dir_entry->dir); #ifdef WIN32 strcat(tmp_full_path, "\\"); #else strcat(tmp_full_path, "/"); #endif strcat(tmp_full_path, file_entry->file); ms_scan_file(s, tmp_full_path, file_entry->type); // Send progress update if necessary if (s->on_progress) { s->progress->done++; if (progress_update(s->progress, tmp_full_path)) send_progress(s); } SIMPLEQ_REMOVE_HEAD(file_head, entries); free(file_entry->file); free(file_entry); } SIMPLEQ_REMOVE_HEAD(dir_head, entries); free(dir_entry->dir); free(dir_entry->files); free(dir_entry); } // Send final progress callback if (s->on_progress) { progress_update(s->progress, NULL); send_progress(s); } LOG_DEBUG("Finished scanning\n"); out: if (s->on_finish) send_finish(s); aborted: if (s->async) { LOG_MEM("destroy thread_data @ %p\n", userdata); free(userdata); } return NULL; }
static void ucomreadcb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status) { struct ucom_softc *sc = (struct ucom_softc *)p; struct tty *tp = sc->sc_tty; struct ucom_buffer *ub; u_int32_t cc; u_char *cp; int s; ub = SIMPLEQ_FIRST(&sc->sc_ibuff_empty); SIMPLEQ_REMOVE_HEAD(&sc->sc_ibuff_empty, ub_link); if (status == USBD_CANCELLED || status == USBD_IOERROR || sc->sc_dying) { DPRINTF(("ucomreadcb: dying\n")); ub->ub_index = ub->ub_len = 0; /* Send something to wake upper layer */ s = spltty(); if (status != USBD_CANCELLED) { (tp->t_linesw->l_rint)('\n', tp); mutex_spin_enter(&tty_lock); /* XXX */ ttwakeup(tp); mutex_spin_exit(&tty_lock); /* XXX */ } splx(s); return; } if (status == USBD_STALLED) { usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe); ucomsubmitread(sc, ub); return; } if (status != USBD_NORMAL_COMPLETION) { printf("ucomreadcb: wonky status=%s\n", usbd_errstr(status)); return; } usbd_get_xfer_status(xfer, NULL, (void *)&cp, &cc, NULL); if (cc == 0) { aprint_normal_dev(sc->sc_dev, "ucomreadcb: zero length xfer!\n"); } KDASSERT(cp == ub->ub_data); #if defined(__NetBSD__) && NRND > 0 rnd_add_uint32(&sc->sc_rndsource, cc); #endif if (sc->sc_opening) { ucomsubmitread(sc, ub); return; } if (sc->sc_methods->ucom_read != NULL) { sc->sc_methods->ucom_read(sc->sc_parent, sc->sc_portno, &cp, &cc); ub->ub_index = (u_int)(cp - ub->ub_data); } else ub->ub_index = 0; ub->ub_len = cc; SIMPLEQ_INSERT_TAIL(&sc->sc_ibuff_full, ub, ub_link); ucom_read_complete(sc); }
void *network_thread (void *data) { struct installer *instp = (struct installer *)data; int ctrllisten, ctrlconnfd; socklen_t clilen; struct sockaddr_un cliaddr; ipc_message msg; int nread; struct msg_elem *notification; int ret; if (!instp) { TRACE("Fatal error: Network thread aborting..."); return (void *)0; } SIMPLEQ_INIT(¬ifymsgs); register_notifier(network_notifier); /* Initialize and bind to UDS */ ctrllisten = listener_create(SOCKET_CTRL_PATH, SOCK_STREAM); if (ctrllisten < 0 ) { TRACE("Error creating IPC sockets"); exit(2); } do { clilen = sizeof(cliaddr); if ( (ctrlconnfd = accept(ctrllisten, (struct sockaddr *) &cliaddr, &clilen)) < 0) { if (errno == EINTR) continue; else { TRACE("Accept returns: %s", strerror(errno)); continue; } } nread = read(ctrlconnfd, (void *)&msg, sizeof(msg)); if (nread != sizeof(msg)) { TRACE("IPC message too short: fragmentation not supported"); close(ctrlconnfd); continue; } #ifdef DEBUG_IPC TRACE("request header: magic[0x%08X] type[0x%08X]", msg.magic, msg.type); #endif pthread_mutex_lock(&stream_mutex); if (msg.magic == IPC_MAGIC) { switch (msg.type) { case REQ_INSTALL: TRACE("Incoming network request: processing..."); if (instp->status == IDLE) { instp->fd = ctrlconnfd; msg.type = ACK; /* Drop all old notification from last run */ cleanum_msg_list(); /* Wake-up the installer */ pthread_cond_signal(&stream_wkup); } else { msg.type = NACK; sprintf(msg.data.msg, "Installation in progress"); } break; case GET_STATUS: msg.type = GET_STATUS; memset(msg.data.msg, 0, sizeof(msg.data.msg)); msg.data.status.current = instp->status; msg.data.status.last_result = instp->last_install; msg.data.status.error = instp->last_error; /* Get first notification from the queue */ pthread_mutex_lock(&msglock); notification = SIMPLEQ_FIRST(¬ifymsgs); if (notification) { SIMPLEQ_REMOVE_HEAD(¬ifymsgs, next); nrmsgs--; strncpy(msg.data.status.desc, notification->msg, sizeof(msg.data.status.desc) - 1); #ifdef DEBUG_IPC printf("GET STATUS: %s\n", msg.data.status.desc); #endif msg.data.status.current = notification->status; msg.data.status.error = notification->error; } pthread_mutex_unlock(&msglock); break; default: msg.type = NACK; } } else { /* Wrong request */ msg.type = NACK; sprintf(msg.data.msg, "Wrong request: aborting"); } ret = write(ctrlconnfd, &msg, sizeof(msg)); if (ret < 0) printf("Error write on socket ctrl"); if (msg.type != ACK) close(ctrlconnfd); pthread_mutex_unlock(&stream_mutex); } while (1); return (void *)0; }
void pcic_event_thread(void *arg) { struct pcic_handle *h = arg; struct pcic_event *pe; int s, first = 1; struct pcic_softc *sc = device_private(h->ph_parent); while (h->shutdown == 0) { /* * Serialize event processing on the PCIC. We may * sleep while we hold this lock. */ mutex_enter(&sc->sc_pcic_lock); s = splhigh(); if ((pe = SIMPLEQ_FIRST(&h->events)) == NULL) { splx(s); if (first) { first = 0; config_pending_decr(sc->dev); } /* * No events to process; release the PCIC lock. */ (void) mutex_exit(&sc->sc_pcic_lock); (void) tsleep(&h->events, PWAIT, "pcicev", 0); continue; } else { splx(s); /* sleep .25s to be enqueued chatterling interrupts */ (void) tsleep((void *)pcic_event_thread, PWAIT, "pcicss", hz / 4); } s = splhigh(); SIMPLEQ_REMOVE_HEAD(&h->events, pe_q); splx(s); switch (pe->pe_type) { case PCIC_EVENT_INSERTION: s = splhigh(); for (;;) { struct pcic_event *pe1, *pe2; if ((pe1 = SIMPLEQ_FIRST(&h->events)) == NULL) break; if (pe1->pe_type != PCIC_EVENT_REMOVAL) break; if ((pe2 = SIMPLEQ_NEXT(pe1, pe_q)) == NULL) break; if (pe2->pe_type == PCIC_EVENT_INSERTION) { SIMPLEQ_REMOVE_HEAD(&h->events, pe_q); free(pe1, M_TEMP); SIMPLEQ_REMOVE_HEAD(&h->events, pe_q); free(pe2, M_TEMP); } } splx(s); DPRINTF(("%s: insertion event\n", device_xname(h->ph_parent))); pcic_attach_card(h); break; case PCIC_EVENT_REMOVAL: s = splhigh(); for (;;) { struct pcic_event *pe1, *pe2; if ((pe1 = SIMPLEQ_FIRST(&h->events)) == NULL) break; if (pe1->pe_type != PCIC_EVENT_INSERTION) break; if ((pe2 = SIMPLEQ_NEXT(pe1, pe_q)) == NULL) break; if (pe2->pe_type == PCIC_EVENT_REMOVAL) { SIMPLEQ_REMOVE_HEAD(&h->events, pe_q); free(pe1, M_TEMP); SIMPLEQ_REMOVE_HEAD(&h->events, pe_q); free(pe2, M_TEMP); } } splx(s); DPRINTF(("%s: removal event\n", device_xname(h->ph_parent))); pcic_detach_card(h, DETACH_FORCE); break; default: panic("pcic_event_thread: unknown event %d", pe->pe_type); } free(pe, M_TEMP); mutex_exit(&sc->sc_pcic_lock); } h->event_thread = NULL; /* In case parent is waiting for us to exit. */ wakeup(sc); kthread_exit(0); }
void recurse_dir(MediaScan *s, const char *path, int recurse_count) { char *dir, *p; char tmp_full_path[MAX_PATH_STR_LEN]; DIR *dirp; struct dirent *dp; struct dirq *subdirq; // list of subdirs of the current directory struct dirq_entry *parent_entry = NULL; // entry for current dir in s->_dirq char redirect_dir[MAX_PATH_STR_LEN]; if (recurse_count > RECURSE_LIMIT) { LOG_ERROR("Hit recurse limit of %d scanning path %s\n", RECURSE_LIMIT, path); return; } if (path[0] != '/') { // XXX Win32 // Get full path char *buf = (char *)malloc((size_t)MAX_PATH_STR_LEN); if (buf == NULL) { FATAL("Out of memory for directory scan\n"); return; } dir = getcwd(buf, (size_t)MAX_PATH_STR_LEN); strcat(dir, "/"); strcat(dir, path); } else { #ifdef USING_TCMALLOC // strdup will cause tcmalloc to crash on free dir = (char *)malloc((size_t)MAX_PATH_STR_LEN); strcpy(dir, path); #else dir = strdup(path); #endif } // Strip trailing slash if any p = &dir[0]; while (*p != 0) { if (p[1] == 0 && *p == '/') *p = 0; p++; } LOG_INFO("Recursed into %s\n", dir); #if defined(__APPLE__) if (isAlias(dir)) { if (CheckMacAlias(dir, redirect_dir)) { LOG_INFO("Resolving Alias %s to %s\n", dir, redirect_dir); strcpy(dir, redirect_dir); } else { LOG_ERROR("Failure to follow symlink or alias, skipping directory\n"); goto out; } } #elif defined(__linux__) if (isAlias(dir)) { FollowLink(dir, redirect_dir); LOG_INFO("Resolving symlink %s to %s\n", dir, redirect_dir); strcpy(dir, redirect_dir); } #endif if ((dirp = opendir(dir)) == NULL) { LOG_ERROR("Unable to open directory %s: %s\n", dir, strerror(errno)); goto out; } subdirq = malloc(sizeof(struct dirq)); SIMPLEQ_INIT(subdirq); while ((dp = readdir(dirp)) != NULL) { char *name = dp->d_name; // skip all dot files if (name[0] != '.') { // Check if scan should be aborted if (unlikely(s->_want_abort)) break; // XXX some platforms may be missing d_type/DT_DIR if (dp->d_type == DT_DIR) { // Add to list of subdirectories we need to recurse into struct dirq_entry *subdir_entry = malloc(sizeof(struct dirq_entry)); // Construct full path //*tmp_full_path = 0; strcpy(tmp_full_path, dir); strcat(tmp_full_path, "/"); strcat(tmp_full_path, name); if (_should_scan_dir(s, tmp_full_path)) { subdir_entry->dir = strdup(tmp_full_path); SIMPLEQ_INSERT_TAIL(subdirq, subdir_entry, entries); LOG_INFO(" subdir: %s\n", tmp_full_path); } else { LOG_INFO(" skipping subdir: %s\n", tmp_full_path); } } else { enum media_type type = _should_scan(s, name); LOG_INFO("name %s = type %d\n", name, type); if (type) { struct fileq_entry *entry; // Check if this file is a shortcut and if so resolve it #if defined(__APPLE__) if (isAlias(name)) { char full_name[MAX_PATH_STR_LEN]; LOG_INFO("Mac Alias detected\n"); strcpy(full_name, dir); strcat(full_name, "\\"); strcat(full_name, name); parse_lnk(full_name, redirect_dir, MAX_PATH_STR_LEN); if (PathIsDirectory(redirect_dir)) { struct dirq_entry *subdir_entry = malloc(sizeof(struct dirq_entry)); subdir_entry->dir = strdup(redirect_dir); SIMPLEQ_INSERT_TAIL(subdirq, subdir_entry, entries); LOG_INFO(" subdir: %s\n", tmp_full_path); type = 0; } } #elif defined(__linux__) if (isAlias(name)) { char full_name[MAX_PATH_STR_LEN]; printf("Linux Alias detected\n"); strcpy(full_name, dir); strcat(full_name, "\\"); strcat(full_name, name); FollowLink(full_name, redirect_dir); if (PathIsDirectory(redirect_dir)) { struct dirq_entry *subdir_entry = malloc(sizeof(struct dirq_entry)); subdir_entry->dir = strdup(redirect_dir); SIMPLEQ_INSERT_TAIL(subdirq, subdir_entry, entries); LOG_INFO(" subdir: %s\n", tmp_full_path); type = 0; } } #endif if (parent_entry == NULL) { // Add parent directory to list of dirs with files parent_entry = malloc(sizeof(struct dirq_entry)); parent_entry->dir = strdup(dir); parent_entry->files = malloc(sizeof(struct fileq)); SIMPLEQ_INIT(parent_entry->files); SIMPLEQ_INSERT_TAIL((struct dirq *)s->_dirq, parent_entry, entries); } // Add scannable file to this directory list entry = malloc(sizeof(struct fileq_entry)); entry->file = strdup(name); entry->type = type; SIMPLEQ_INSERT_TAIL(parent_entry->files, entry, entries); s->progress->total++; LOG_INFO(" [%5d] file: %s\n", s->progress->total, entry->file); } } } } closedir(dirp); // Send progress update if (s->on_progress && !s->_want_abort) if (progress_update(s->progress, dir)) send_progress(s); // process subdirs while (!SIMPLEQ_EMPTY(subdirq)) { struct dirq_entry *subdir_entry = SIMPLEQ_FIRST(subdirq); SIMPLEQ_REMOVE_HEAD(subdirq, entries); if (!s->_want_abort) recurse_dir(s, subdir_entry->dir, recurse_count); free(subdir_entry); } free(subdirq); out: free(dir); }