void Dispatcher::yield() { assert(GetCurrentThreadId() == threadId); for (;;) { LARGE_INTEGER frequency; LARGE_INTEGER ticks; QueryPerformanceCounter(&ticks); QueryPerformanceFrequency(&frequency); uint64_t currentTime = ticks.QuadPart / (frequency.QuadPart / 1000); auto timerContextPair = timers.begin(); auto end = timers.end(); while (timerContextPair != end && timerContextPair->first <= currentTime) { timerContextPair->second->interruptProcedure = nullptr; pushContext(timerContextPair->second); timerContextPair = timers.erase(timerContextPair); } OVERLAPPED_ENTRY entries[16]; ULONG actual = 0; if (GetQueuedCompletionStatusEx(completionPort, entries, 16, &actual, 0, TRUE) == TRUE) { assert(actual > 0); for (ULONG i = 0; i < actual; ++i) { if (entries[i].lpOverlapped == reinterpret_cast<LPOVERLAPPED>(remoteSpawnOverlapped)) { EnterCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(criticalSection)); assert(remoteNotificationSent); assert(!remoteSpawningProcedures.empty()); do { spawn(std::move(remoteSpawningProcedures.front())); remoteSpawningProcedures.pop(); } while (!remoteSpawningProcedures.empty()); remoteNotificationSent = false; LeaveCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(criticalSection)); continue; } NativeContext* context = reinterpret_cast<DispatcherContext*>(entries[i].lpOverlapped)->context; context->interruptProcedure = nullptr; pushContext(context); } } else { DWORD lastError = GetLastError(); if (lastError == WAIT_TIMEOUT) { break; } else if (lastError != WAIT_IO_COMPLETION) { throw std::runtime_error("Dispatcher::yield, GetQueuedCompletionStatusEx failed, " + errorMessage(lastError)); } } } if (firstResumingContext != nullptr) { pushContext(currentContext); dispatch(); } }
void Dispatcher::yield() { for(;;){ epoll_event events[16]; int count = epoll_wait(epoll, events, 16, 0); if (count == 0) { break; } if(count > 0) { for(int i = 0; i < count; ++i) { ContextPair *contextPair = static_cast<ContextPair*>(events[i].data.ptr); if(((events[i].events & (EPOLLIN | EPOLLOUT)) != 0) && contextPair->readContext == nullptr && contextPair->writeContext == nullptr) { uint64_t buf; auto transferred = read(remoteSpawnEvent, &buf, sizeof buf); if(transferred == -1) { throw std::runtime_error("Dispatcher::dispatch, read(remoteSpawnEvent) failed, " + lastErrorMessage()); } MutextGuard guard(*reinterpret_cast<pthread_mutex_t*>(this->mutex)); while (!remoteSpawningProcedures.empty()) { spawn(std::move(remoteSpawningProcedures.front())); remoteSpawningProcedures.pop(); } continue; } if ((events[i].events & EPOLLOUT) != 0) { contextPair->writeContext->context->interruptProcedure = nullptr; pushContext(contextPair->writeContext->context); contextPair->writeContext->events = events[i].events; } else if ((events[i].events & EPOLLIN) != 0) { contextPair->readContext->context->interruptProcedure = nullptr; pushContext(contextPair->readContext->context); contextPair->readContext->events = events[i].events; } else { continue; } } } else { if (errno != EINTR) { throw std::runtime_error("Dispatcher::dispatch, epoll_wait failed, " + lastErrorMessage()); } } } if (firstResumingContext != nullptr) { pushContext(currentContext); dispatch(); } }
void ScriptEngine::importProgram(const QScriptProgram &program, const QScriptValue &scope, QScriptValue &targetObject) { QSet<QString> globalPropertyNames; { QScriptValueIterator it(globalObject()); while (it.hasNext()) { it.next(); globalPropertyNames += it.name(); } } pushContext(); if (scope.isObject()) currentContext()->pushScope(scope); QScriptValue result = evaluate(program); QScriptValue activationObject = currentContext()->activationObject(); if (scope.isObject()) currentContext()->popScope(); popContext(); if (Q_UNLIKELY(hasErrorOrException(result))) throw ErrorInfo(tr("Error when importing '%1': %2").arg(program.fileName(), result.toString())); // If targetObject is already an object, it doesn't get overwritten but enhanced by the // contents of the .js file. // This is necessary for library imports that consist of multiple js files. if (!targetObject.isObject()) targetObject = newObject(); // Copy every property of the activation object to the target object. // We do not just save a reference to the activation object, because QScriptEngine contains // special magic for activation objects that leads to unanticipated results. { QScriptValueIterator it(activationObject); while (it.hasNext()) { it.next(); if (debugJSImports) qDebug() << "[ENGINE] Copying property " << it.name(); targetObject.setProperty(it.name(), it.value()); } } // Copy new global properties to the target object and remove them from // the global object. This is to support direct variable assignments // without the 'var' keyword in JavaScript files. QScriptValueIterator it(globalObject()); while (it.hasNext()) { it.next(); if (globalPropertyNames.contains(it.name())) continue; if (debugJSImports) { qDebug() << "[ENGINE] inserting global property " << it.name() << " " << it.value().toString(); } targetObject.setProperty(it.name(), it.value()); it.remove(); } }
void NamespaceSupport::reset() { _contexts.clear(); pushContext(); declarePrefix(XML_NAMESPACE_PREFIX, XML_NAMESPACE); declarePrefix(XMLNS_NAMESPACE_PREFIX, XMLNS_NAMESPACE); }
static gboolean gst_openal_sink_unprepare (GstAudioSink * audiosink) { GstOpenALSink *sink = GST_OPENAL_SINK (audiosink); ALCcontext *old; if (!sink->default_context) return TRUE; old = pushContext (sink->default_context); alSourceStop (sink->default_source); alSourcei (sink->default_source, AL_BUFFER, 0); if (!sink->user_source) alDeleteSources (1, &sink->default_source); sink->default_source = 0; alDeleteBuffers (sink->buffer_count, sink->buffers); g_free (sink->buffers); sink->buffers = NULL; sink->buffer_idx = 0; sink->buffer_count = 0; sink->buffer_length = 0; checkALError (); popContext (old, sink->default_context); if (!sink->user_context) alcDestroyContext (sink->default_context); sink->default_context = NULL; return TRUE; }
static guint gst_openal_sink_delay (GstAudioSink * asink) { GstOpenALSink *openal = GST_OPENAL_SINK (asink); ALint queued, state, offset, delay; ALCcontext *old; if (!openal->context) return 0; GST_OPENAL_SINK_LOCK (openal); old = pushContext (openal->context); delay = 0; alGetSourcei (openal->sID, AL_BUFFERS_QUEUED, &queued); /* Order here is important. If the offset is queried after the state and an * underrun occurs in between the two calls, it can end up with a 0 offset * in a playing state, incorrectly reporting a len*queued/bps delay. */ alGetSourcei (openal->sID, AL_BYTE_OFFSET, &offset); alGetSourcei (openal->sID, AL_SOURCE_STATE, &state); /* Note: state=stopped is an underrun, meaning all buffers are processed * and there's no delay when writing the next buffer. Pre-buffering is * state=initial, which will introduce a delay while writing. */ if (checkALError () == AL_NO_ERROR && state != AL_STOPPED) delay = ((queued * openal->bID_length) - offset) / openal->bytes_per_sample; popContext (old, openal->context); GST_OPENAL_SINK_UNLOCK (openal); return delay; }
static gboolean gst_openal_sink_unprepare (GstAudioSink * asink) { GstOpenALSink *openal = GST_OPENAL_SINK (asink); ALCcontext *old; if (!openal->context) return TRUE; old = pushContext (openal->context); alSourceStop (openal->sID); alSourcei (openal->sID, AL_BUFFER, 0); if (!openal->custom_sID) alDeleteSources (1, &openal->sID); openal->sID = 0; alDeleteBuffers (openal->bID_count, openal->bIDs); g_free (openal->bIDs); openal->bIDs = NULL; openal->bID_idx = 0; openal->bID_count = 0; openal->bID_length = 0; checkALError (); popContext (old, openal->context); if (!openal->custom_ctx) alcDestroyContext (openal->context); openal->context = NULL; return TRUE; }
int main(int argc, const char * argv[]) { char code[1000] = ""; FILE *fp = fopen(argv[1], "r"); int i = 0; char c; while((c = fgetc(fp)) != EOF){ code[i++] = c; } fclose(fp); code[i] = '\0'; VM* vm = newVM(); Context* global = newContext(); Contexts* contexts = newContexts(); pushContext(contexts, global); Method* methods[MAX_METHOD_NUM] = { defineMethod("+", method_add), defineMethod("add", method_add), defineMethod("-", method_minus), defineMethod("minus", method_minus), defineMethod("*", method_multiply), defineMethod("multiply", method_multiply), defineMethod("/", method_divide), defineMethod("divide", method_divide), defineMethod("\\", method_last), defineMethod("last", method_last) }; return execute(code, vm, contexts, methods); }
NetMessageReader::NetMessageReader(const Buffer* buf) : buffer_(buf), pos_(0), currentContext_(nullptr), begin_(0), argSize_(0) { pushContext(); // create root context }
Control::Control() : current_context(0), _M_skipFunctionBody(false), _M_lexer(0), _M_parser(0) { pushContext(); declareTypedef(findOrInsertName("__builtin_va_list", strlen("__builtin_va_list")), 0); }
void ParserEngine::parseExternal(XML_Parser extParser, InputSource* pInputSource) { pushContext(extParser, pInputSource); if (pInputSource->getCharacterStream()) parseExternalCharInputStream(extParser, *pInputSource->getCharacterStream()); else if (pInputSource->getByteStream()) parseExternalByteInputStream(extParser, *pInputSource->getByteStream()); else throw XMLException("Input source has no stream"); popContext(); }
void Interpreter::execute(Code* code) { //cout << "Executing.." << endl; _code = code; pushContext(0); executeFun(0); //cout << "Stack sizes: " << _stack.size() << " " << _typeStack.size() << endl; }
void Dispatcher::interruptTimer(uint64_t time, NativeContext* context) { assert(GetCurrentThreadId() == threadId); auto range = timers.equal_range(time); for (auto it = range.first; ; ++it) { assert(it != range.second); if (it->second == context) { pushContext(context); timers.erase(it); break; } } }
void doVehException(EXCEPTION_RECORD *rec, unsigned int handler) { cpuToContext(); unsigned int ctx_ptr = pushContext(); unsigned int rec_ptr = pushExceptionRecord(rec); push(ctx_ptr, SIZE_DWORD); push(rec_ptr, SIZE_DWORD); push(esp, SIZE_DWORD); push(VEH_MAGIC, SIZE_DWORD); //handler return address //need to execute exception handler here setup flag to trap ret //set eip to start of exception handler and resume fetching cpu.eip = handler; }
void ParserEngine::parse(const char* pBuffer, std::size_t size) { init(); resetContext(); InputSource src; pushContext(_parser, &src); if (_pContentHandler) _pContentHandler->setDocumentLocator(this); if (_pContentHandler) _pContentHandler->startDocument(); if (!XML_Parse(_parser, pBuffer, static_cast<int>(size), 1)) handleError(XML_GetErrorCode(_parser)); if (_pContentHandler) _pContentHandler->endDocument(); popContext(); }
void Generator::visitCursorChildren(CXCursor cursor, Generator::Visitor callback) const { VisitorWrapper wrapper = [&callback, this](const CXCursor &self, const CXCursor &parent) { pushContext(self, parent); auto ret = callback(); popContext(); return ret; }; CXClientData data = reinterpret_cast<CXClientData>(&wrapper); clang_visitChildren(cursor, childVisitor, data); }
void Interpreter::call() { uint16_t funId = getNext2Bytes(); pushContext(funId); loadFunParamsInCtx(funId); stackTrace.push(CallInfo(_bc, _insPtr)); _bc = ((BytecodeFunction*)_code->functionById(funId))->bytecode(); _insPtr = 0; // popContext(); }
void ParserEngine::parse(InputSource* pInputSource) { init(); resetContext(); pushContext(_parser, pInputSource); if (_pContentHandler) _pContentHandler->setDocumentLocator(this); if (_pContentHandler) _pContentHandler->startDocument(); if (pInputSource->getCharacterStream()) parseCharInputStream(*pInputSource->getCharacterStream()); else if (pInputSource->getByteStream()) parseByteInputStream(*pInputSource->getByteStream()); else throw XMLException("Input source has no stream"); if (_pContentHandler) _pContentHandler->endDocument(); popContext(); }
void GemWindow::render(void){ if(!makeCurrent()) { error("unable to switch to current window (do you have one?), cannot render!"); return; } if(!pushContext()) { error("unable to switch to current context, cannot render!"); return; } bang(); if(m_buffer==2) swapBuffers(); popContext(); }
bool XLIFFHandler::startElement( const QString& namespaceURI, const QString& localName, const QString& /*qName*/, const QXmlAttributes& atts ) { if (namespaceURI == m_URI || namespaceURI == m_URI12) { if (localName == QLatin1String("xliff")) { // make sure that the stack is not empty during parsing pushContext(XC_xliff); } else if (localName == QLatin1String("file")) { m_fileName = atts.value(QLatin1String("original")); m_language = atts.value(QLatin1String("target-language")); } else if (localName == QLatin1String("group")) { pushContext(XC_group); if (atts.value(QLatin1String("restype")) == QLatin1String(restypeContext)) { m_context = atts.value(QLatin1String("resname")); } else { if (atts.value(QLatin1String("restype")) == QLatin1String(restypePlurals)) { pushContext(XC_restype_plurals); } m_comment.clear(); } } else if (localName == QLatin1String("trans-unit")) { if (atts.value(QLatin1String("translate")) == QLatin1String("no")) { m_type = TranslatorMessage::Obsolete; } m_comment.clear(); } else if (localName == QLatin1String("target")) { QString state = atts.value(QLatin1String("state")); if (state == QLatin1String("new")) { m_type = TranslatorMessage::Unfinished; } else if (state == QLatin1String("final")) { m_type = TranslatorMessage::Finished; } } else if (localName == QLatin1String("context-group")) { QString purpose = atts.value(QLatin1String("purpose")); if (purpose == QLatin1String("location")) { pushContext(XC_context_group); } } else if (currentContext() == XC_context_group && localName == QLatin1String("context")) { if ( atts.value(QLatin1String("context-type")) == QLatin1String("linenumber")) pushContext(XC_context_linenumber); } else if (localName == QLatin1String("ph")) { QString ctype = atts.value(QLatin1String("ctype")); if (ctype.startsWith(QLatin1String("x-ch-"))) { m_ctype = ctype.mid(5); } pushContext(XC_ph); } if (currentContext() != XC_ph) accum.clear(); return true; } return false; }
/* Used at the beginning of a new scope (begin of a * definition, parenthesis...) to catch inner let * definition that may be in. */ static void mayRedeclare (vString * const ident, ocaToken what) { switch (what) { case OcaKEYWORD_value: /* let globalScope handle it */ globalScope (ident, what); break; case OcaKEYWORD_let: case OcaKEYWORD_val: toDoNext = localLet; break; case OcaKEYWORD_object: vStringClear (lastClass); pushContext (ContextStrong, ContextClass, &localScope, NULL /*voidName */ ); needStrongPoping = FALSE; toDoNext = &globalScope; break; case OcaKEYWORD_for: case OcaKEYWORD_while: toDoNext = &tillToken; waitedToken = OcaKEYWORD_do; comeAfter = &mayRedeclare; break; case OcaKEYWORD_try: toDoNext = &mayRedeclare; pushSoftContext (matchPattern, ident, ContextFunction); break; case OcaKEYWORD_fun: toDoNext = &matchPattern; break; /* Handle the special ;; from the OCaml * Top level */ case Tok_semi: default: toDoNext = &localScope; localScope (ident, what); } }
void doSehException(EXCEPTION_RECORD *rec) { unsigned int err_ptr = readMem(fsBase, SIZE_DWORD); unsigned int handler = readMem(err_ptr + 4, SIZE_DWORD); //err->handler //do sanity checks on handler here? cpuToContext(); unsigned int ctx_ptr = pushContext(); unsigned int rec_ptr = pushExceptionRecord(rec); push(ctx_ptr, SIZE_DWORD); push(err_ptr, SIZE_DWORD); //err_ptr == fsBase?? push(rec_ptr, SIZE_DWORD); push(SEH_MAGIC, SIZE_DWORD); //handler return address //need to execute exception handler here setup flag to trap ret //set eip to start of exception handler and resume fetching cpu.eip = handler; }
static void gst_openal_sink_reset (GstAudioSink * asink) { GstOpenALSink *openal = GST_OPENAL_SINK (asink); ALCcontext *old; GST_OPENAL_SINK_LOCK (openal); old = pushContext (openal->context); openal->write_reset = AL_TRUE; alSourceStop (openal->sID); alSourceRewind (openal->sID); alSourcei (openal->sID, AL_BUFFER, 0); checkALError (); popContext (old, openal->context); GST_OPENAL_SINK_UNLOCK (openal); }
static void gst_openal_sink_reset (GstAudioSink * audiosink) { GstOpenALSink *sink = GST_OPENAL_SINK (audiosink); ALCcontext *old; GST_OPENAL_SINK_LOCK (sink); old = pushContext (sink->default_context); sink->write_reset = AL_TRUE; alSourceStop (sink->default_source); alSourceRewind (sink->default_source); alSourcei (sink->default_source, AL_BUFFER, 0); checkALError (); popContext (old, sink->default_context); GST_OPENAL_SINK_UNLOCK (sink); }
void Dispatcher::spawn(std::function<void()>&& procedure) { NativeContext* context = &getReusableContext(); if(contextGroup.firstContext != nullptr) { context->groupPrev = contextGroup.lastContext; assert(contextGroup.lastContext->groupNext == nullptr); contextGroup.lastContext->groupNext = context; } else { context->groupPrev = nullptr; contextGroup.firstContext = context; contextGroup.firstWaiter = nullptr; } context->interrupted = false; context->group = &contextGroup; context->groupNext = nullptr; context->procedure = std::move(procedure); contextGroup.lastContext = context; pushContext(context); }
void ParserEngine::parse(const char* pBuffer, std::size_t size) { init(); resetContext(); InputSource src; pushContext(_parser, &src); if (_pContentHandler) _pContentHandler->setDocumentLocator(this); if (_pContentHandler) _pContentHandler->startDocument(); std::size_t processed = 0; while (processed < size) { const int bufferSize = processed + PARSE_BUFFER_SIZE < size ? PARSE_BUFFER_SIZE : static_cast<int>(size - processed); if (!XML_Parse(_parser, pBuffer + processed, bufferSize, 0)) handleError(XML_GetErrorCode(_parser)); processed += bufferSize; } if (!XML_Parse(_parser, pBuffer+processed, 0, 1)) handleError(XML_GetErrorCode(_parser)); if (_pContentHandler) _pContentHandler->endDocument(); popContext(); }
static guint gst_openal_sink_delay (GstAudioSink * audiosink) { GstOpenALSink *sink = GST_OPENAL_SINK (audiosink); ALint queued, state, offset, delay; ALCcontext *old; if (!sink->default_context) return 0; GST_OPENAL_SINK_LOCK (sink); old = pushContext (sink->default_context); delay = 0; alGetSourcei (sink->default_source, AL_BUFFERS_QUEUED, &queued); /* Order here is important. If the offset is queried after the state and an * underrun occurs in between the two calls, it can end up with a 0 offset * in a playing state, incorrectly reporting a len*queued/bps delay. */ alGetSourcei (sink->default_source, AL_BYTE_OFFSET, &offset); alGetSourcei (sink->default_source, AL_SOURCE_STATE, &state); /* Note: state=stopped is an underrun, meaning all buffers are processed * and there's no delay when writing the next buffer. Pre-buffering is * state=initial, which will introduce a delay while writing. */ if (checkALError () == AL_NO_ERROR && state != AL_STOPPED) delay = ((queued * sink->buffer_length) - offset) / sink->bytes_per_sample / sink->channels / GST_MSECOND; popContext (old, sink->default_context); GST_OPENAL_SINK_UNLOCK (sink); if (G_UNLIKELY (delay < 0)) { /* make sure we never return a negative delay */ GST_WARNING_OBJECT (openal_debug, "negative delay"); delay = 0; } return delay; }
void CEvaluator::visit ( CApply* e ) { CFunction *f= getFunction(e->getFunction()); if(!f) { throw(EvaluationError("function \""+e->getFunction()+"\" is not defined.")); } if(!f || (f->getNumArguments() != e->getNumArguments())) { throw(EvaluationError("number of arguments for function \""+e->getFunction()+"\" does not match declaration.")); } map<string,int> *newContext= new map<string,int>(); for(int i=0; i<f->getNumArguments();i++) { string tmp=f->getArgument(i)->getName(); e->getArgument(i)->accept(this); int value=result; // cout << " "<< tmp <<"="<<value<<endl; (*newContext)[tmp]=value; } pushContext(newContext); CExpr *e2 = f->getExpression(); e2->accept(this); delete popContext(); //return result; }
static gint gst_openal_sink_write (GstAudioSink * audiosink, gpointer data, guint length) { GstOpenALSink *sink = GST_OPENAL_SINK (audiosink); ALint processed, queued, state; ALCcontext *old; gulong rest_us; g_assert (length == sink->buffer_length); old = pushContext (sink->default_context); rest_us = (guint64) (sink->buffer_length / sink->bytes_per_sample) * G_USEC_PER_SEC / sink->rate / sink->channels; do { alGetSourcei (sink->default_source, AL_SOURCE_STATE, &state); alGetSourcei (sink->default_source, AL_BUFFERS_QUEUED, &queued); alGetSourcei (sink->default_source, AL_BUFFERS_PROCESSED, &processed); if (checkALError () != AL_NO_ERROR) { GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (NULL), ("Source state error detected")); length = 0; goto out_nolock; } if (processed > 0 || queued < sink->buffer_count) break; if (state != AL_PLAYING) alSourcePlay (sink->default_source); g_usleep (rest_us); } while (1); GST_OPENAL_SINK_LOCK (sink); if (sink->write_reset != AL_FALSE) { sink->write_reset = AL_FALSE; length = 0; goto out; } queued -= processed; while (processed-- > 0) { ALuint bid; alSourceUnqueueBuffers (sink->default_source, 1, &bid); } if (state == AL_STOPPED) { /* "Restore" from underruns (not actually needed, but it keeps delay * calculations correct while rebuffering) */ alSourceRewind (sink->default_source); } alBufferData (sink->buffers[sink->buffer_idx], sink->format, data, sink->buffer_length, sink->rate); alSourceQueueBuffers (sink->default_source, 1, &sink->buffers[sink->buffer_idx]); sink->buffer_idx = (sink->buffer_idx + 1) % sink->buffer_count; queued++; if (state != AL_PLAYING && queued == sink->buffer_count) alSourcePlay (sink->default_source); if (checkALError () != AL_NO_ERROR) { GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (NULL), ("Source queue error detected")); goto out; } out: GST_OPENAL_SINK_UNLOCK (sink); out_nolock: popContext (old, sink->default_context); return length; }
static gboolean gst_openal_sink_prepare (GstAudioSink * audiosink, GstAudioRingBufferSpec * spec) { GstOpenALSink *sink = GST_OPENAL_SINK (audiosink); ALCcontext *context, *old; if (sink->default_context && !gst_openal_sink_unprepare (audiosink)) return FALSE; if (sink->user_context) context = sink->user_context; else { ALCint attribs[3] = { 0, 0, 0 }; /* Don't try to change the playback frequency of an app's device */ if (!sink->user_device) { attribs[0] = ALC_FREQUENCY; attribs[1] = GST_AUDIO_INFO_RATE (&spec->info); attribs[2] = 0; } context = alcCreateContext (sink->default_device, attribs); if (!context) { GST_ELEMENT_ERROR (sink, RESOURCE, FAILED, ("Unable to prepare device."), GST_ALC_ERROR (sink->default_device)); return FALSE; } } old = pushContext (context); if (sink->user_source) { if (!sink->user_context || !alIsSource (sink->user_source)) { GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND, (NULL), ("Invalid source specified for context")); goto fail; } sink->default_source = sink->user_source; } else { ALuint source; alGenSources (1, &source); if (checkALError () != AL_NO_ERROR) { GST_ELEMENT_ERROR (sink, RESOURCE, NO_SPACE_LEFT, (NULL), ("Unable to generate source")); goto fail; } sink->default_source = source; } gst_openal_sink_parse_spec (sink, spec); if (sink->format == AL_NONE) { GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS, (NULL), ("Unable to get type %d, format %d, and %d channels", spec->type, GST_AUDIO_INFO_FORMAT (&spec->info), GST_AUDIO_INFO_CHANNELS (&spec->info))); goto fail; } sink->buffers = g_malloc (sink->buffer_count * sizeof (*sink->buffers)); if (!sink->buffers) { GST_ELEMENT_ERROR (sink, RESOURCE, FAILED, ("Out of memory."), ("Unable to allocate buffers")); goto fail; } alGenBuffers (sink->buffer_count, sink->buffers); if (checkALError () != AL_NO_ERROR) { GST_ELEMENT_ERROR (sink, RESOURCE, NO_SPACE_LEFT, (NULL), ("Unable to generate %d buffers", sink->buffer_count)); goto fail; } sink->buffer_idx = 0; popContext (old, context); sink->default_context = context; return TRUE; fail: if (!sink->user_source && sink->default_source) alDeleteSources (1, &sink->default_source); sink->default_source = 0; g_free (sink->buffers); sink->buffers = NULL; sink->buffer_count = 0; sink->buffer_length = 0; popContext (old, context); if (!sink->user_context) alcDestroyContext (context); return FALSE; }