Beispiel #1
0
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);
    }
}
Beispiel #2
0
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;
}
Beispiel #3
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(&notifymsgs);
        SIMPLEQ_REMOVE_HEAD(&notifymsgs, 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(&notifymsgs, newmsg, next);
    pthread_mutex_unlock(&msglock);
}
Beispiel #4
0
Datei: umidi.c Projekt: bluhm/sys
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);
	}
}
Beispiel #5
0
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);
}
Beispiel #6
0
/*
 * 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;
}
Beispiel #8
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);
	}
}
Beispiel #9
0
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;
}
Beispiel #10
0
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;
}
Beispiel #11
0
/*
 * 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;
		}
	}
}
Beispiel #12
0
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);
}
Beispiel #13
0
/*
 * 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;
}
Beispiel #14
0
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);
	}
}
Beispiel #15
0
static void cleanum_msg_list(void)
{
    struct msg_elem *notification;

    pthread_mutex_lock(&msglock);

    while (!SIMPLEQ_EMPTY(&notifymsgs)) {
        notification = SIMPLEQ_FIRST(&notifymsgs);
        SIMPLEQ_REMOVE_HEAD(&notifymsgs, next);
        free(notification);
    }
    nrmsgs = 0;
    pthread_mutex_unlock(&msglock);
}
Beispiel #16
0
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);
       }
}
Beispiel #18
0
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);
}
Beispiel #20
0
//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);

}
Beispiel #21
0
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;
	}
}
Beispiel #22
0
/*
 * 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);
}
Beispiel #24
0
/*
 * 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);
}
Beispiel #25
0
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);
}
Beispiel #26
0
// 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;
}
Beispiel #27
0
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);
}
Beispiel #28
0
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(&notifymsgs);
    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(&notifymsgs);
                if (notification) {
                    SIMPLEQ_REMOVE_HEAD(&notifymsgs, 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;
}
Beispiel #29
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);
}