コード例 #1
0
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();
  }
}
コード例 #2
0
ファイル: Dispatcher.cpp プロジェクト: RAY-official/catalyst
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();
  }
}
コード例 #3
0
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();
    }
}
コード例 #4
0
ファイル: NamespaceSupport.cpp プロジェクト: 12307/poco
void NamespaceSupport::reset()
{
	_contexts.clear();
	pushContext();
	declarePrefix(XML_NAMESPACE_PREFIX, XML_NAMESPACE);
	declarePrefix(XMLNS_NAMESPACE_PREFIX, XMLNS_NAMESPACE);
}
コード例 #5
0
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;
}
コード例 #6
0
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;
}
コード例 #7
0
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;
}
コード例 #8
0
ファイル: executor.c プロジェクト: nighca/lang
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);
}
コード例 #9
0
NetMessageReader::NetMessageReader(const Buffer* buf) :
	buffer_(buf),
	pos_(0),
	currentContext_(nullptr),
	begin_(0),
	argSize_(0)
{
	pushContext(); // create root context
}
コード例 #10
0
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);
}
コード例 #11
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();
}
コード例 #12
0
ファイル: Interpreter.cpp プロジェクト: nvmd/spbau-mathvm
void Interpreter::execute(Code* code)
{
    //cout << "Executing.." << endl;

	_code = code;
    pushContext(0);
    executeFun(0);

    //cout << "Stack sizes: " << _stack.size() << " " << _typeStack.size() << endl;

}
コード例 #13
0
ファイル: Dispatcher.cpp プロジェクト: HBNCoins/cryptonote
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;
    }
  }
}
コード例 #14
0
ファイル: seh.cpp プロジェクト: IDA-RE-things/ida-x86emu-QT
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;
}
コード例 #15
0
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();
}
コード例 #16
0
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);
}
コード例 #17
0
ファイル: Interpreter.cpp プロジェクト: nvmd/spbau-mathvm
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();

}
コード例 #18
0
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();
}
コード例 #19
0
ファイル: GemWindow.cpp プロジェクト: avilleret/Gem
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();
}
コード例 #20
0
ファイル: xliff.cpp プロジェクト: FilipBE/qtextended
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;
}
コード例 #21
0
ファイル: ocaml.c プロジェクト: b4n/fishman-ctags
/* 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);
	}
}
コード例 #22
0
ファイル: seh.cpp プロジェクト: IDA-RE-things/ida-x86emu-QT
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;
}
コード例 #23
0
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);
}
コード例 #24
0
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);
}
コード例 #25
0
ファイル: Dispatcher.cpp プロジェクト: RAY-official/catalyst
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);
}
コード例 #26
0
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();
}
コード例 #27
0
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;
}
コード例 #28
0
ファイル: CEvaluator.cpp プロジェクト: AmrEledkawy/slps
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;
}
コード例 #29
0
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;
}
コード例 #30
0
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;
}