Пример #1
0
static int
insert_queue(struct seq_oss_devinfo *dp, union evrec *rec, struct file *opt)
{
	int rc = 0;
	struct snd_seq_event event;

	/* if this is a timing event, process the current time */
	if (snd_seq_oss_process_timer_event(dp->timer, rec))
		return 0; /* no need to insert queue */

	/* parse this event */
	memset(&event, 0, sizeof(event));
	/* set dummy -- to be sure */
	event.type = SNDRV_SEQ_EVENT_NOTEOFF;
	snd_seq_oss_fill_addr(dp, &event, dp->addr.port, dp->addr.client);

	if (snd_seq_oss_process_event(dp, rec, &event))
		return 0; /* invalid event - no need to insert queue */

	event.time.tick = snd_seq_oss_timer_cur_tick(dp->timer);
	if (dp->timer->realtime || !dp->timer->running) {
		snd_seq_oss_dispatch(dp, &event, 0, 0);
	} else {
		if (is_nonblock_mode(dp->file_mode))
			rc = snd_seq_kernel_client_enqueue(dp->cseq, &event, 0, 0);
		else
			rc = snd_seq_kernel_client_enqueue_blocking(dp->cseq, &event, opt, 0, 0);
	}
	return rc;
}
Пример #2
0
/*
 * wait until the write buffer has enough room
 */
int
snd_seq_oss_writeq_sync(seq_oss_writeq_t *q)
{
	seq_oss_devinfo_t *dp = q->dp;
	abstime_t time;
	unsigned long flags;

	time = snd_seq_oss_timer_cur_tick(dp->timer);
	if (q->sync_time >= time)
		return 0; /* already finished */

	if (! q->sync_event_put) {
		snd_seq_event_t ev;
		evrec_t *rec;

		/* put echoback event */
		memset(&ev, 0, sizeof(ev));
		ev.flags = 0;
		ev.type = SNDRV_SEQ_EVENT_ECHO;
		ev.time.tick = time;
		/* echo back to itself */
		snd_seq_oss_fill_addr(dp, &ev, dp->addr.client, dp->addr.port);
		rec = (evrec_t*)&ev.data;
		rec->t.code = SEQ_SYNCTIMER;
		rec->t.time = time;
		q->sync_event_put = 1;
		snd_seq_kernel_client_enqueue_blocking(dp->cseq, &ev, NULL, 0, 0);
	}

	spin_lock_irqsave(&q->sync_lock, flags);
	if (! q->sync_event_put) { /* echoback event has been received */
		spin_unlock_irqrestore(&q->sync_lock, flags);
		return 0;
	}
		
	/* wait for echo event */
	spin_unlock(&q->sync_lock);
	interruptible_sleep_on_timeout(&q->sync_sleep, HZ);
	spin_lock(&q->sync_lock);
	if (signal_pending(current)) {
		/* interrupted - return 0 to finish sync */
		q->sync_event_put = 0;
		spin_unlock_irqrestore(&q->sync_lock, flags);
		return 0;
	}
	spin_unlock_irqrestore(&q->sync_lock, flags);
	if (q->sync_time >= time)
		return 0;
	else
		return 1;
}
Пример #3
0
/*
 * wait until the write buffer has enough room
 */
int
snd_seq_oss_writeq_sync(struct seq_oss_writeq *q)
{
	struct seq_oss_devinfo *dp = q->dp;
	abstime_t time;

	time = snd_seq_oss_timer_cur_tick(dp->timer);
	if (q->sync_time >= time)
		return 0; /* already finished */

	if (! q->sync_event_put) {
		struct snd_seq_event ev;
		union evrec *rec;

		/* put echoback event */
		memset(&ev, 0, sizeof(ev));
		ev.flags = 0;
		ev.type = SNDRV_SEQ_EVENT_ECHO;
		ev.time.tick = time;
		/* echo back to itself */
		snd_seq_oss_fill_addr(dp, &ev, dp->addr.client, dp->addr.port);
		rec = (union evrec *)&ev.data;
		rec->t.code = SEQ_SYNCTIMER;
		rec->t.time = time;
		q->sync_event_put = 1;
		snd_seq_kernel_client_enqueue_blocking(dp->cseq, &ev, NULL, 0, 0);
	}

	wait_event_interruptible_timeout(q->sync_sleep, ! q->sync_event_put, HZ);
	if (signal_pending(current))
		/* interrupted - return 0 to finish sync */
		q->sync_event_put = 0;
	if (! q->sync_event_put || q->sync_time >= time)
		return 0;
	return 1;
}