Exemple #1
0
static INLINE void send_event(part_evtlist_t *evlist, void **val, bool (*match_func)(void **a, void **b))
{
	elistdata_t  eld_p;
	mempart_evt_t  *reg_event = get_first_event(evlist, &eld_p);

	while (reg_event != NULL)
	{
		struct evt_info_s *evt = &reg_event->evt_reg;

		if (reg_event->onlist == &evlist->active)
		{
			/* if this event has been deactivated, don't send it */
			if (evt->flags & evtflags_DEACTIVATE) {
				deactivate_event(evlist, (part_evt_t *)reg_event);
			}
			/* check for event send conditions */
			else if (reg_event->evt_dest.rcvid > 0)
			{
				void **compare_val_p = GET_COMPARE_VAL_P(evt);
				CRASHCHECK(compare_val_p == NULL);

				/*
				 * if the caller did not provide a match function, or a match
				 * function was provided and it returns TRUE, deliver the event
				*/
				if ((match_func == NULL) ||
					(match_func(compare_val_p, val) == bool_t_TRUE))
				{
					int r;
					struct sigevent se = evt->sig;		// make a local copy
					/*
					 * if the caller has set evtflags_SIGEV_FLAG_SIGINFO, we
					 * can return some useful information
					*/
					if (evt->flags & evtflags_SIGEV_FLAG_SIGINFO) {
						se.sigev_value.sival_ptr = *val;
					}
					r = apm_deliver_event(&reg_event->evt_dest, &se);

					if (r == EOK) reg_event->undeliverable_count = 0;
					else if (r == ESRCH) ++reg_event->undeliverable_count;

					if ((reg_event->undeliverable_count > ORPHAN_RETRY_COUNT) ||
						(!(evt->flags & evtflags_REARM)))
					{
						/* remove the event from the list */
						deactivate_event(evlist, (part_evt_t *)reg_event);
					}
				}
			}
		}
		reg_event = get_next_event(evlist, reg_event, &eld_p);
	}
}
Exemple #2
0
// * Must be called when deleting a patch or track. (why?)
// * Can't there be hanging notes, or other undefined behaviors, when the event callback is not called?
// Returns true if everything was cleared.
bool SCHEDULER_clear(void){
  //printf("TODO: Implermnet SCHEDULER_clear\n");

  const int max_to_remove = 20; // 2048/20 = 102.4. 102.4 * 64 frames / (48000 frames / seconds) = 0.1365 seconds. I.e. we should never wait more than approx. 0.14 seconds for all events to be cleared.
  int num_removed = 0;
  
  while(g_queue_size>0 && num_removed < max_to_remove){
    event_t *event = get_first_event();
    remove_first_event();
    release_event(event);
    num_removed++;
  }

  if (g_queue_size > 0)
    return false;
  else
    return true;
}
Exemple #3
0
void SCHEDULER_called_per_block(int64_t reltime){
  int64_t end_time = g_current_time + reltime;

  while(g_queue_size>0){
    event_t *event = get_first_event();
    int64_t event_time = event->time >> SCHEDULER_NUM_PRIORITY_BITS;  // remove priority bits.
    if(event_time < end_time){
      remove_first_event();
      {
        event->callback(scheduler_to_seq_time(event_time), &event->args[0]); // note that the callback can also schedule new events
      }
      release_event(event);
    }else
      break;
  }

  g_current_time = end_time;
}
Exemple #4
0
static INLINE void
send_delta_events(part_evtlist_t *evlist, memsize_t cur_size, memsize_t prev_size,
					bool (*compare_func)(memsize_t delta, memsize_t last_sz, memsize_t cur_sz))
{
	elistdata_t  eld_p;
	mempart_evt_t  *reg_event = get_first_event(evlist, &eld_p);

	while (reg_event != NULL)
	{
		struct evt_info_s *evt = &reg_event->evt_reg;

		if (reg_event->onlist == &evlist->active)
		{
			memsize_t *delta_p = GET_DELTA_P(evt);
			CRASHCHECK(delta_p == NULL);

			initial_delta_conditions_check(reg_event, prev_size, (void *)compare_func);

			/* if this event has been deactivated, don't send it */
			if (evt->flags & evtflags_DEACTIVATE) {
				deactivate_event(evlist, (part_evt_t *)reg_event);
			}
			/* check for event send conditions */
			else if ((reg_event->evt_dest.rcvid > 0) &&
					 ((compare_func == NULL) ||
					  (compare_func(*delta_p, reg_event->evt_data.size, cur_size) == bool_t_TRUE)))
			{
				int r;
				struct sigevent se = evt->sig;		// make a local copy
				/*
				 * if the caller has set evtflags_SIGEV_FLAG_SIGINFO, we
				 * can return some useful information
				*/
				if (evt->flags & evtflags_SIGEV_FLAG_SIGINFO)
				{
					/*
					 * if the 'cur_size' is too large to fit in the sival_int field
					 * then send back UINT_MAX. This otherwise illegal size value
					 * (because UINT_MAX & (__PAGESIZE - 1) != 0) will be an indication
					 * to the event receiver that o information was provided and
					 * that they need to request the current size if they need it
					*/
					if (cur_size > UINT_MAX) {
						se.sigev_value.sival_int = UINT_MAX;
					} else {
						se.sigev_value.sival_int = (_Uint32t)cur_size;
					}
				}
				r = apm_deliver_event(&reg_event->evt_dest, &se);

				if (r == EOK) reg_event->undeliverable_count = 0;
				else if (r == ESRCH) ++reg_event->undeliverable_count;

				if ((reg_event->undeliverable_count > ORPHAN_RETRY_COUNT) ||
					(!(evt->flags & evtflags_REARM)))
				{
					/* remove the event from the list */
					deactivate_event(evlist, (part_evt_t *)reg_event);
				}
				else {
					reg_event->evt_data.size = cur_size;
				}
			}
		}
		reg_event = get_next_event(evlist, reg_event, &eld_p);
	}
}