void RThread::handleOutput (char *buf, int buf_length) {
	RK_TRACE (RBACKEND);

// TODO: output sometimes arrives in small chunks. Maybe it would be better to keep an internal buffer, and only append it to the output, when R_FlushConsole gets called?

	if (!buf_length) return;
	waitIfOutputPaused ();

	MUTEX_LOCK;
	if (current_output) {
		if (current_output->type != ROutput::Output) {
			flushOutput ();
		}
	}
	if (!current_output) {	// not an else, might have been set to 0 in the above if
		current_output = new ROutput;
		current_output->type = ROutput::Output;
		current_output->output.reserve (MAX_BUF_LENGTH + 50);
	}
	current_output->output.append (QString::fromLocal8Bit (buf));

	if ((out_buf_len += buf_length) > MAX_BUF_LENGTH) {
		RK_DO (qDebug ("Output buffer has %d characters. Forcing flush", out_buf_len), RBACKEND, DL_DEBUG);
		flushOutput ();
	}
	MUTEX_UNLOCK;
}
Beispiel #2
0
    /**
     * allocates a new buffer for the next write iterations
     */
    void generateOutputBuffer( int amountOfChannels )
    {
        flushOutput(); // free previous contents
        cachedBuffer = new AudioBuffer( amountOfChannels, outputBufferSize );

        outputWriterIndex = 0;
    }
void AltSoftSerial::end(void)
{
	DISABLE_INT_COMPARE_B();
	DISABLE_INT_INPUT_CAPTURE();
	flushInput();
	flushOutput();
	DISABLE_INT_COMPARE_A();
	// TODO: restore timer to original settings?
}
Beispiel #4
0
int Serial::write(str *data) {
    unsigned char c;
    for(int i=0; i<data->unit.size(); i++) {
        c = data->unit[i];
        ssize_t result = ::write(fd, &c, 1);
        assert(result==1);
    }
    flushOutput();
    flushInput();
}
Beispiel #5
0
/*
 *  Process one request
 */
static void processRequest() 
{
    char        *appName, *url;
    int         flags;

    appName = mprStrdup(mpr, pathInfo);
    if (*appName == '/') {
        appName++;
    }
    if ((url = strchr(appName, '/')) != 0) {
        *url++ = '\0';
    }
    if (strncmp(url, "web/", 4) == 0) {
        copyFile(url);
        flushOutput(output);
        return;
    }

    /*
     *  Set default response headers
     */
    setHeader(NULL, 0, "Content-Type", "text/html");
    setHeader(NULL, 0, "Last-Modified", currentDate);
    setHeader(NULL, 0, "Cache-Control", "no-cache");

    flags = 0;
    if (ext == 0) {
        flags |= EJS_WEB_FLAG_APP;
    }
    if ((web = ejsCreateWebRequest(mpr, control, NULL, scriptName, pathInfo, documentRoot, flags)) == 0) {
        error(NULL, 0, "Can't create web request");
        return;
    }
    ejs = web->ejs;

    if (ejsRunWebRequest(web) < 0) {
        error(NULL, 0, "%s", web->error);
        return;
    }
    flushOutput(output);
}
Beispiel #6
0
static int
writeLine (void) {
  if (inputCarriageReturn)
    if (!writeByte('\r'))
      return 0;

  if (writeByte('\n'))
    if (flushOutput())
      return 1;

  return 0;
}
Beispiel #7
0
/*
 *  Emit all headers
 */
static void emitHeaders()
{
    MprHash     *hp;
    int         len;

    hp = mprGetFirstHash(responseHeaders);
    while (hp) {
        len = strlen(hp->key) + strlen(hp->data) + 4;
        if (mprGetBufSpace(headerOutput) < len) {
            flushOutput(headerOutput);
        }
        mprPutStringToBuf(headerOutput, hp->key);
        mprPutStringToBuf(headerOutput, ": ");
        mprPutStringToBuf(headerOutput, hp->data);
        mprPutStringToBuf(headerOutput, "\r\n");
        hp = mprGetNextHash(responseHeaders, hp);
    }
    mprPutStringToBuf(headerOutput, "\r\n");
    flushOutput(headerOutput);
    headersEmitted = 1;
}
Beispiel #8
0
static int
writeBytes (const char *bytes, size_t length) {
  while (length) {
    size_t count = OUTPUT_SIZE - outputLength;
    if (length < count) count = length;
    memcpy(&outputBuffer[outputLength], bytes, count);
    bytes += count;
    length -= count;
    if ((outputLength += count) == OUTPUT_SIZE)
      if (!flushOutput())
        return 0;
  }

  return 1;
}
void RThread::handleError (QString *call, int call_length) {
	RK_TRACE (RBACKEND);

	if (!call_length) return;
	waitIfOutputPaused ();

	MUTEX_LOCK;
	// Unfortunately, errors still get printed to the output. We try this crude method for the time being:
	flushOutput ();
	current_command->output_list.last ()->type = ROutput::Error;
	current_command->status |= RCommand::HasError;

	RK_DO (qDebug ("error '%s'", call[0].latin1 ()), RBACKEND, DL_DEBUG);
	MUTEX_UNLOCK;
}
Beispiel #10
0
/*
 *  Write data to the client. Will buffer and flush as required. will create headers if required.
 */
static int writeBlock(void *handle, cchar *buf, int size)
{
    int     len, rc;

    len = mprGetBufLength(output);
    if ((len + size) < EJS_CGI_MAX_BUF) {
        rc = mprPutBlockToBuf(output, buf, size);
    } else {
        flushOutput(output);
        if (size < EJS_CGI_MAX_BUF) {
            rc = mprPutBlockToBuf(output, buf, size);
        } else {
            rc = write(1, (char*) buf, size);
        }
    }
    return rc;
}
Beispiel #11
0
    /**
     * write the contents of the write buffer into
     * an output file, this will only write content
     * up until the point if was written to in case
     * the buffer wasn't full yet
     */
    void writeBufferToFile( int aSampleRate, int aNumChannels, bool broadcastUpdate )
    {
        // quick assertion
        if ( cachedBuffer == 0 )
            return;

        // copy string contents for appending of filename
        std::string outputFile = std::string( outputDirectory.c_str());

        int bufferSize = outputBufferSize;

        // recorded less than maximum available in buffer ? cut silence
        // by writing recording into temporary buffers

        if ( outputWriterIndex < bufferSize )
        {
            bufferSize = outputWriterIndex;

            AudioBuffer* tempBuffer = new AudioBuffer( aNumChannels, bufferSize );

            for ( int i = 0; i < bufferSize; ++i )
            {
                for ( int c = 0; c < aNumChannels; ++c )
                    tempBuffer->getBufferForChannel( c )[ i ] = cachedBuffer->getBufferForChannel( c )[ i ];
            }

            WaveWriter::bufferToFile( outputFile.append( SSTR( AudioEngine::recordingFileId )),
                                      tempBuffer, aSampleRate );

            // free memory allocated by temporary buffer

            delete tempBuffer;
        }
        else
        {
            WaveWriter::bufferToFile( outputFile.append( SSTR( AudioEngine::recordingFileId )),
                                      cachedBuffer, aSampleRate );
        }

        flushOutput(); // free memory

        // broadcast update, pass buffer identifier to identify last recording
        if ( broadcastUpdate )
            Notifier::broadcast( Notifications::RECORDING_STATE_UPDATED, AudioEngine::recordingFileId );
    }
void RThread::handleSubstackCall (QString *call, int call_length) {
	RK_TRACE (RBACKEND);

	RCommand *prev_command = current_command;
	REvalRequest *request = new REvalRequest;
	request->call = call;
	request->call_length = call_length;
	MUTEX_LOCK;
	flushOutput ();
	RCommandStack *reply_stack = new RCommandStack ();
	request->in_chain = reply_stack->startChain (reply_stack);
	MUTEX_UNLOCK;

	QCustomEvent *event = new QCustomEvent (R_EVAL_REQUEST_EVENT);
	event->setData (request);
	qApp->postEvent (RKGlobals::rInterface (), event);
	
	bool done = false;
	while (!done) {
		MUTEX_LOCK;
		processX11Events ();
		// while commands are in queue, don't wait
		while (reply_stack->isActive () && !locked) {
			RCommand *command = reply_stack->pop ();
			
			if (command) {
				// mutex will be unlocked inside
				doCommand (command);
				processX11Events ();
			}
		}

		if (reply_stack->isEmpty ()) {
			done = true;
		}
		MUTEX_UNLOCK;

		// if no commands are in queue, sleep for a while
		current_command = prev_command;
		msleep (10);
	}

	delete reply_stack;
}
void RThread::handleStandardCallback (RCallbackArgs *args) {
	RK_TRACE (RBACKEND);

	MUTEX_LOCK;
	flushOutput ();
	MUTEX_UNLOCK;
	args->done = false;

	QCustomEvent *event = new QCustomEvent (R_CALLBACK_REQUEST_EVENT);
	event->setData (args);
	qApp->postEvent (RKGlobals::rInterface (), event);
	
	bool *done = &(args->done);
	while (!(*done)) {
		msleep (10); // callback not done yet? Sleep for a while

		if (!locked) {			// what's with that lock? If the current command is cancelled, while we're in this loop, we must not lock the mutex and/or call anything in R. We may get long-jumped out of the loop before we get a chance to unlock
			MUTEX_LOCK;
			if (!locked) processX11Events ();
			MUTEX_UNLOCK;
		}
	}
}
RInterface::RInterface () {
	RK_TRACE (RBACKEND);
	
#ifndef DISABLE_RKWINDOWCATCHER
	window_catcher = new RKWindowCatcher (0);
	window_catcher->hide ();
#endif // DISABLE_RKWINDOWCATCHER
	
// If R_HOME is not set, most certainly the user called the binary without the wrapper script
	if (!getenv ("R_HOME")) {
		RK_DO (qDebug ("No R_HOME environment variable set. RKWard will quit in a moment. Always start rkward in the default way unless you know what you're doing."), RBACKEND, DL_ERROR);
	}

	RCommandStack::regular_stack = new RCommandStack ();
	running_command_canceled = 0;
	
	r_thread = new RThread ();

	watch = new RKwatch ();

	flush_timer = new QTimer (this);
	connect (flush_timer, SIGNAL (timeout ()), this, SLOT (flushOutput ()));
	flush_timer->start (FLUSH_INTERVAL);
}
int RThread::initialize () {
	RK_TRACE (RBACKEND);

	// we create a fake RCommand to capture all the output/errors during startup
	current_command = new RCommand (i18n ("R Startup"), RCommand::App, i18n ("R Startup"));

	int argc = 2;
	char* argv[2] = { qstrdup ("--slave"), qstrdup ("--no-save") };

	startR (argc, argv);

	for (--argc; argc >= 0; --argc) {
		delete argv[argc];
	}

	connectCallbacks ();

	RKWardRError error;
	int status = 0;
	
	runCommandInternal ("library (\"rkward\")\n", &error);
	if (error) status |= LibLoadFail;
	int c;
	QString *paths = getCommandAsStringVector ("library.dynam (\"rkward\", \"rkward\")[[\"path\"]]\n", &c, &error);
	if ((error) || (c != 1)) {
		status |= LibLoadFail;
	} else {
		if (!registerFunctions (paths[0].local8Bit ())) status |= LibLoadFail;
	}
	delete [] paths;

// find out about standard library locations
	QString *standardliblocs = getCommandAsStringVector (".libPaths ()\n", &c, &error);
	if (error) status |= OtherFail;
	for (int i = 0; i < c; ++i) {
		RKSettingsModuleRPackages::defaultliblocs.append (standardliblocs[i]);
	}
	delete [] standardliblocs;

// apply user configurable run time options
	QStringList commands = RKSettingsModuleR::makeRRunTimeOptionCommands () + RKSettingsModuleRPackages::makeRRunTimeOptionCommands ();
	for (QStringList::const_iterator it = commands.begin (); it != commands.end (); ++it) {
		runCommandInternal ((*it).local8Bit (), &error);
		if (error) {
			status |= OtherFail;
			RK_DO (qDebug ("error in initialization call '%s'", (*it).latin1()), RBACKEND, DL_ERROR);
		}
	}

// error sink and help browser
	runCommandInternal ("options (error=quote (.rk.do.error ()))\n", &error);
	if (error) status |= SinkFail;
/*	runCommandInternal (".rk.init.handlers ()\n", &error);
	if (error) status |= SinkFail; */
	runCommandInternal ("options (htmlhelp=TRUE); options (browser=\"dcop " + kapp->dcopClient ()->appId () + " rkwardapp openHTMLHelp \")", &error);
	if (error) status |= OtherFail;
	// TODO: error-handling?

	MUTEX_LOCK;
	flushOutput ();
	MUTEX_UNLOCK;
	QCustomEvent *event = new QCustomEvent (RCOMMAND_OUT_EVENT);
	event->setData (current_command);
	qApp->postEvent (RKGlobals::rInterface (), event);

	return status;
}
Beispiel #16
0
void Component::flushAll()
{
	flushInput();
	flushOutput();
}
void RThread::doCommand (RCommand *command) {
	RK_TRACE (RBACKEND);
	// step 1: notify GUI-thread that a new command is being tried and initialize
	QCustomEvent *event = new QCustomEvent (RCOMMAND_IN_EVENT);
	event->setData (command);
	qApp->postEvent (RKGlobals::rInterface (), event);
	current_command = command;

	// step 2: actual handling
	if (!((command->type () & RCommand::EmptyCommand) || (command->status & RCommand::Canceled))) {
		RKWardRError error;
		
		int ctype = command->type ();
		QCString localc = command->command ().local8Bit ();		// needed so the string below does not go out of scope
		const char *ccommand = localc;
		
		RK_DO (qDebug ("running command: %s", ccommand), RBACKEND, DL_DEBUG);
	
		if (command->type () & RCommand::DirectToOutput) {
			runCommandInternal (QString ("sink (\"" + RKSettingsModuleGeneral::filesPath () + "/rk_out.html\", append=TRUE, split=TRUE)\n").local8Bit (), &error);
		}

		MUTEX_UNLOCK;
	
		if (ctype & RCommand::GetStringVector) {
			command->string_data = getCommandAsStringVector (ccommand, &(command->string_count), &error);
		} else if (ctype & RCommand::GetRealVector) {
			command->real_data = getCommandAsRealVector (ccommand, &(command->real_count), &error);
		} else if (ctype & RCommand::GetIntVector) {
			command->integer_data = getCommandAsIntVector (ccommand, &(command->integer_count), &error);
		} else {
			runCommandInternal (ccommand, &error, ctype & RCommand::User);
		}

		MUTEX_LOCK;

		#ifdef RKWARD_DEBUG
			int dl = DL_WARNING;		// failed application commands are an issue worth reporting, failed user commands are not
			if (command->type () | RCommand::User) dl = DL_DEBUG;
		#endif
		if (error != NoError) {
			command->status |= RCommand::WasTried | RCommand::Failed;
			if (error == Incomplete) {
				command->status |= RCommand::ErrorIncomplete;
				RK_DO (qDebug ("Command failed (incomplete)"), RBACKEND, dl);
			} else if (error == SyntaxError) {
				command->status |= RCommand::ErrorSyntax;
				RK_DO (qDebug ("Command failed (syntax)"), RBACKEND, dl);
			} else if (command->status & RCommand::Canceled) {
				RK_DO (qDebug ("Command failed (interrupted)"), RBACKEND, dl);
			} else {
				command->status |= RCommand::ErrorOther;
				#ifdef RKWARD_DEBUG
					dl = DL_WARNING;		// always interested in strange errors
				#endif
				RK_DO (qDebug ("Command failed (other)"), RBACKEND, dl);
			}
			RK_DO (qDebug ("failed command was: '%s'", command->command ().latin1 ()), RBACKEND, dl);
		} else {
			command->status |= RCommand::WasTried;
		}
	
		RKWardRError dummy;
		if (command->type () & RCommand::DirectToOutput) {
			runCommandInternal ("sink ()\n", &dummy);
		}
	
		if (error) {
			RK_DO (qDebug ("- error message was: '%s'", command->error ().latin1 ()), RBACKEND, dl);
	//		runCommandInternal (".rk.init.handlers ()\n", &dummy);
		}
		RK_DO (qDebug ("done running command"), RBACKEND, DL_DEBUG);

		flushOutput ();
	}

	// step 3: cleanup
	// notify GUI-thread that command was finished
	event = new QCustomEvent (RCOMMAND_OUT_EVENT);
	event->setData (command);
	qApp->postEvent (RKGlobals::rInterface (), event);
}
Beispiel #18
0
rtems_status_code
rtems_termios_ioctl (void *arg)
{
  rtems_libio_ioctl_args_t *args = arg;
  struct rtems_termios_tty *tty = args->iop->data1;
  struct ttywakeup         *wakeup = (struct ttywakeup *)args->buffer;
  rtems_status_code sc;

  args->ioctl_return = 0;
  sc = rtems_semaphore_obtain (tty->osem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
  if (sc != RTEMS_SUCCESSFUL) {
    return sc;
  }
  switch (args->command) {
  default:
    if (rtems_termios_linesw[tty->t_line].l_ioctl != NULL) {
      sc = rtems_termios_linesw[tty->t_line].l_ioctl(tty,args);
    }
    else {
      sc = RTEMS_INVALID_NUMBER;
    }
    break;

  case RTEMS_IO_GET_ATTRIBUTES:
    *(struct termios *)args->buffer = tty->termios;
    break;

  case RTEMS_IO_SET_ATTRIBUTES:
    tty->termios = *(struct termios *)args->buffer;

    /* check for and process change in flow control options */
    termios_set_flowctrl(tty);

    if (tty->termios.c_lflag & ICANON) {
      tty->rawInBufSemaphoreOptions = RTEMS_WAIT;
      tty->rawInBufSemaphoreTimeout = RTEMS_NO_TIMEOUT;
      tty->rawInBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT;
    } else {
      tty->vtimeTicks = tty->termios.c_cc[VTIME] * 
                    rtems_clock_get_ticks_per_second() / 10;
      if (tty->termios.c_cc[VTIME]) {
        tty->rawInBufSemaphoreOptions = RTEMS_WAIT;
        tty->rawInBufSemaphoreTimeout = tty->vtimeTicks;
        if (tty->termios.c_cc[VMIN])
          tty->rawInBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT;
        else
          tty->rawInBufSemaphoreFirstTimeout = tty->vtimeTicks;
      } else {
        if (tty->termios.c_cc[VMIN]) {
          tty->rawInBufSemaphoreOptions = RTEMS_WAIT;
          tty->rawInBufSemaphoreTimeout = RTEMS_NO_TIMEOUT;
          tty->rawInBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT;
        } else {
          tty->rawInBufSemaphoreOptions = RTEMS_NO_WAIT;
        }
      }
    }
    if (tty->handler.set_attributes) {
      sc = (*tty->handler.set_attributes)(tty, &tty->termios) ?
        RTEMS_SUCCESSFUL : RTEMS_IO_ERROR;
    }
    break;

  case RTEMS_IO_TCDRAIN:
    drainOutput (tty);
    break;

  case RTEMS_IO_TCFLUSH:
    switch ((intptr_t) args->buffer) {
      case TCIFLUSH:
        flushInput (tty);
        break;
      case TCOFLUSH:
        flushOutput (tty);
        break;
      case TCIOFLUSH:
        flushOutput (tty);
        flushInput (tty);
        break;
      default:
        sc = RTEMS_INVALID_NAME;
        break;
    }
    break;

  case RTEMS_IO_SNDWAKEUP:
    tty->tty_snd = *wakeup;
    break;

  case RTEMS_IO_RCVWAKEUP:
    tty->tty_rcv = *wakeup;
    break;

    /*
     * FIXME: add various ioctl code handlers
     */

#if 1 /* FIXME */
  case TIOCSETD:
    /*
     * close old line discipline
     */
    if (rtems_termios_linesw[tty->t_line].l_close != NULL) {
      sc = rtems_termios_linesw[tty->t_line].l_close(tty);
    }
    tty->t_line=*(int*)(args->buffer);
    tty->t_sc = NULL; /* ensure that no more valid data */
    /*
     * open new line discipline
     */
    if (rtems_termios_linesw[tty->t_line].l_open != NULL) {
      sc = rtems_termios_linesw[tty->t_line].l_open(tty);
    }
    break;
  case TIOCGETD:
    *(int*)(args->buffer)=tty->t_line;
    break;
#endif
   case FIONREAD: {
      int rawnc = tty->rawInBuf.Tail - tty->rawInBuf.Head;
      if ( rawnc < 0 )
        rawnc += tty->rawInBuf.Size;
      /* Half guess that this is the right operation */
      *(int *)args->buffer = tty->ccount - tty->cindex + rawnc;
    }
    break;
  }

  rtems_semaphore_release (tty->osem);
  return sc;
}