void SetPortValue::execute(ProcessContext& context) { Event::execute(context); assert(_time >= context.start() && _time <= context.end()); if (_port && _port->context() == Context::MESSAGE) return; apply(context); _engine.control_bindings()->port_value_changed(context, _port); }
unsigned PreProcessor::process(ProcessContext& context, PostProcessor& dest, size_t limit) { Event* const head = _head.load(); if (!head) { return 0; } size_t n_processed = 0; Event* ev = head; Event* last = ev; while (ev && ev->is_prepared() && ev->time() < context.end()) { if (ev->time() < context.start()) { // Didn't get around to executing in time, oh well... ev->set_time(context.start()); } ev->execute(context); last = ev; ev = ev->next(); ++n_processed; if (limit && n_processed >= limit) { break; } } if (n_processed > 0) { Event* next = (Event*)last->next(); last->next(NULL); dest.append(context, head, last); // Since _head was not NULL, we know it hasn't been changed since _head = next; /* If next is NULL, then _tail may now be invalid. However, it would cause a race to reset _tail here. Instead, append() checks only _head for emptiness, and resets the tail appropriately. */ } return n_processed; }
/** Signal the end of a cycle that has produced messages. * AUDIO THREAD ONLY. */ inline void signal(ProcessContext& context) { ThreadManager::assert_thread(THREAD_PROCESS); const Request cycle_end_request(context.end(), NULL); _requests.write(sizeof(Request), &cycle_end_request); _sem.post(); }