TEST(AsyncTimerMock, BasicTest) { AsyncTimerFactoryMock factory; // Set an early timer bool timer1Fired = false; auto timer1 = factory.make(Milliseconds(1000)); timer1->asyncWait([&timer1Fired](std::error_code ec) { ASSERT(!ec); timer1Fired = true; }); // Set a later timer bool timer2Fired = false; auto timer2 = factory.make(Milliseconds(2000)); timer2->asyncWait([&timer2Fired](std::error_code ec) { ASSERT(!ec); timer2Fired = true; }); // Advance clock a little, nothing should fire factory.fastForward(Milliseconds(500)); ASSERT(!timer1Fired); ASSERT(!timer2Fired); // Advance clock so early timer fires factory.fastForward(Milliseconds(600)); ASSERT(timer1Fired); // Second timer should still be waiting ASSERT(!timer2Fired); // Advance clock so second timer fires factory.fastForward(Milliseconds(1000)); ASSERT(timer2Fired); }
TEST(AsyncTimerMock, WorksAfterCancel) { AsyncTimerFactoryMock factory; // Set a timer bool fired1 = false; auto timer = factory.make(Milliseconds(100)); timer->asyncWait([&fired1](std::error_code ec) { // This timer should have been canceled ASSERT(ec); ASSERT(ec == asio::error::operation_aborted); fired1 = true; }); // Cancel timer timer->cancel(); // Ensure that its handler was called ASSERT(fired1); fired1 = false; bool fired2 = false; // Add a new callback to to timer. timer->asyncWait([&fired2](std::error_code ec) { // This timer should NOT have been canceled ASSERT(!ec); fired2 = true; }); // Fast forward so it expires factory.fastForward(Milliseconds(100)); ASSERT(fired2); ASSERT(!fired1); }
int playBeep (unsigned short frequency, unsigned int duration) { if (asynchronousBeep(frequency, duration*4)) { asyncWait(duration); stopBeep(); return 1; } if (startBeep(frequency)) { asyncWait(duration); stopBeep(); return 1; } return synchronousBeep(frequency, duration); }
void drainBrailleOutput (BrailleDisplay *brl, int minimumDelay) { int duration = brl->writeDelay + 1; brl->writeDelay = 0; if (duration < minimumDelay) duration = minimumDelay; asyncWait(duration); }
void Signals::asyncWait() { set.async_wait([this] (ErrorCode err, int signal) { if (err) { std::cerr << "Signal handling error: " << err.message() << std::endl; return; } dispatchSignalHandler(signal); asyncWait(); }); }
Signals::Signals(boost::asio::io_service& service) : set(service) { set.add(SIGINT); set.add(SIGTERM); #ifndef _WIN32 set.add(SIGUSR1); set.add(SIGHUP); #endif asyncWait(); }
static int fmTone (NoteDevice *device, unsigned int duration, NoteFrequency frequency) { uint32_t pitch = frequency; logMessage(LOG_DEBUG, "tone: MSecs:%u Freq:%"PRIu32, duration, pitch); if (pitch) { fmPlayTone(device->channelNumber, pitch, duration, prefs.fmVolume); } else { asyncWait(duration); } return 1; }
int serialPollInput (SerialDevice *serial, int timeout) { TimePeriod period; if (timeout) startTimePeriod(&period, timeout); while (1) { if (serialTestInput(serial)) return 1; if (!timeout) break; if (afterTimePeriod(&period, NULL)) break; asyncWait(1); } errno = EAGAIN; return 0; }
static int modifyFileLock (int file, int mode) { int ok = 0; off_t offset; if ((offset = lseek(file, 0, SEEK_CUR)) != -1) { if (lseek(file, 0, SEEK_SET) != -1) { int wait; if (mode == _LK_LOCK) { mode = _LK_NBLCK; wait = 1; } else if (mode == _LK_RLCK) { mode = _LK_NBRLCK; wait = 1; } else { wait = 0; } while (1) { if (_locking(file, mode, LONG_MAX) != -1) { ok = 1; break; } if (errno != EACCES) { logSystemError("_locking"); break; } if (!wait) break; asyncWait(1000); } if (lseek(file, offset, SEEK_SET) == -1) { logSystemError("lseek"); ok = 0; } } else { logSystemError("lseek"); } } else { logSystemError("lseek"); } return ok; }
TEST(AsyncTimerMock, Cancel) { AsyncTimerFactoryMock factory; // Set a timer bool fired = false; auto timer = factory.make(Milliseconds(100)); timer->asyncWait([&fired](std::error_code ec) { // This timer should have been canceled ASSERT(ec); ASSERT(ec == asio::error::operation_aborted); fired = true; }); // Cancel timer timer->cancel(); // Ensure that its handler was called ASSERT(fired); }
static int readKey (void) { unsigned char key; unsigned char arg; if (serialReadData(serialDevice, &key, 1, 0, 0) != 1) return EOF; switch (key) { default: arg = 0; break; case KEY_FUNCTION: case KEY_FUNCTION2: case KEY_UPDATE: while (serialReadData(serialDevice, &arg, 1, 0, 0) != 1) asyncWait(1); break; } { int result = COMPOUND_KEY(key, arg); logMessage(LOG_DEBUG, "Key read: %4.4X", result); return result; } }
TEST(AsyncTimerMock, CancelExpired) { AsyncTimerFactoryMock factory; // Set a timer bool fired = false; auto timer = factory.make(Milliseconds(100)); timer->asyncWait([&fired](std::error_code ec) { // This timer should NOT have been canceled ASSERT(!ec); fired = true; }); // Fast forward so it expires factory.fastForward(Milliseconds(200)); ASSERT(fired); fired = false; // Cancel it, should not fire again timer->cancel(); ASSERT(!fired); }
ToggleResult toggleBit ( int *bits, int bit, int command, const TuneDefinition *offTune, const TuneDefinition *onTune ) { int oldBits = *bits; switch (command & BRL_FLG_TOGGLE_MASK) { case 0: *bits ^= bit; break; case BRL_FLG_TOGGLE_ON: *bits |= bit; break; case BRL_FLG_TOGGLE_OFF: *bits &= ~bit; break; default: playTune(&tune_command_rejected); return TOGGLE_ERROR; } { int isOn = (*bits & bit) != 0; const TuneDefinition *tune = isOn? onTune: offTune; playTune(tune); if (*bits != oldBits) return isOn? TOGGLE_ON: TOGGLE_OFF; asyncWait(TUNE_TOGGLE_REPEAT_DELAY); playTune(tune); return TOGGLE_SAME; } }
static int awaitUsbInput (GioHandle *handle, int timeout) { UsbChannel *channel = handle->channel; { GioUsbAwaitInputMethod *method = handle->properties.awaitInput; if (method) { return method(channel->device, channel->definition, timeout); } } { unsigned char endpoint = channel->definition->inputEndpoint; if (!endpoint) { asyncWait(timeout); return 0; } return usbAwaitInput(channel->device, endpoint, timeout); } }
static int brl_construct (BrailleDisplay *brl, char **parameters, const char *device) { short n, success; /* loop counters, flags, etc. */ unsigned char *init_seq = (unsigned char *)"\002\0330"; /* string to send to Braille to initialise: [ESC][0] */ unsigned char *init_ack = (unsigned char *)"\002\033V"; /* string to expect as acknowledgement: [ESC][V]... */ unsigned char c; TimePeriod period; if (!isSerialDevice(&device)) { unsupportedDevice(device); return 0; } brlcols = -1; /* length of braille display (auto-detected) */ prevdata = rawdata = NULL; /* clear pointers */ /* No need to load translation tables, as these are now * defined in tables.h */ /* Now open the Braille display device for random access */ if (!(MB_serialDevice = serialOpenDevice(device))) goto failure; if (!serialRestartDevice(MB_serialDevice, BAUDRATE)) goto failure; if (!serialSetFlowControl(MB_serialDevice, SERIAL_FLOW_HARDWARE)) goto failure; /* MultiBraille initialisation procedure: * [ESC][V][Braillelength][Software Version][CR] * I guess, they mean firmware version with software version :*} * firmware version == [Software Version] / 10.0 */ success = 0; if (init_seq[0]) if (serialWriteData (MB_serialDevice, init_seq + 1, init_seq[0]) != init_seq[0]) goto failure; startTimePeriod (&period, ACK_TIMEOUT); /* initialise timeout testing */ n = 0; do { asyncWait (20); if (serialReadData (MB_serialDevice, &c, 1, 0, 0) == 0) continue; if (n < init_ack[0] && c != init_ack[1 + n]) continue; if (n == init_ack[0]) { brlcols = c, success = 1; /* reading version-info */ /* firmware version == [Software Version] / 10.0 */ serialReadData (MB_serialDevice, &c, 1, 0, 0); logMessage (LOG_INFO, "MultiBraille: Version: %2.1f", c/10.0); /* read trailing [CR] */ serialReadData (MB_serialDevice, &c, 1, 0, 0); } n++; } while (!afterTimePeriod (&period, NULL) && n <= init_ack[0]); if (success && (brlcols > 0)) { if ((prevdata = malloc(brlcols))) { if ((rawdata = malloc(20 + (brlcols * 2)))) { brl->textColumns = brlcols; brl->textRows = 1; brl->statusColumns = 5; brl->statusRows = 1; { static const DotsTable dots = { 0X01, 0X02, 0X04, 0X80, 0X40, 0X20, 0X08, 0X10 }; makeOutputTable(dots); } return 1; } else { logMallocError(); } free(prevdata); } else { logMallocError(); } } failure: if (MB_serialDevice) { serialCloseDevice(MB_serialDevice); MB_serialDevice = NULL; } return 0; }
static int brl_readCommand (BrailleDisplay *brl, KeyTableCommandContext context) { int key = readKey(); if (context != currentContext) { logMessage(LOG_DEBUG, "Context switch: %d -> %d", currentContext, context); switch (currentContext = context) { case KTB_CTX_DEFAULT: deviceStatus = DEV_ONLINE; break; default: break; } } if (key != EOF) { switch (key) { case KEY_FUNCTION_ENTER: return BRL_CMD_KEY(ENTER); case KEY_FUNCTION_TAB: return BRL_CMD_KEY(TAB); case KEY_FUNCTION_CURSOR_UP: return BRL_CMD_KEY(CURSOR_UP); case KEY_FUNCTION_CURSOR_DOWN: return BRL_CMD_KEY(CURSOR_DOWN); case KEY_FUNCTION_CURSOR_LEFT: return BRL_CMD_KEY(CURSOR_LEFT); case KEY_FUNCTION_CURSOR_RIGHT: return BRL_CMD_KEY(CURSOR_RIGHT); case KEY_FUNCTION_CURSOR_UP_JUMP: return BRL_CMD_KEY(HOME); case KEY_FUNCTION_CURSOR_DOWN_JUMP: return BRL_CMD_KEY(END); case KEY_FUNCTION_CURSOR_LEFT_JUMP: return BRL_CMD_KEY(PAGE_UP); case KEY_FUNCTION_CURSOR_RIGHT_JUMP: return BRL_CMD_KEY(PAGE_DOWN); case KEY_FUNCTION_F1: return BRL_CMD_KFN(1); case KEY_FUNCTION_F2: return BRL_CMD_KFN(2); case KEY_FUNCTION_F3: return BRL_CMD_KFN(3); case KEY_FUNCTION_F4: return BRL_CMD_KFN(4); case KEY_FUNCTION_F5: return BRL_CMD_KFN(5); case KEY_FUNCTION_F6: return BRL_CMD_KFN(6); case KEY_FUNCTION_F7: return BRL_CMD_KFN(7); case KEY_FUNCTION_F9: return BRL_CMD_KFN(9); case KEY_FUNCTION_F10: return BRL_CMD_KFN(10); case KEY_COMMAND: { int command; while ((command = readKey()) == EOF) asyncWait(1); logMessage(LOG_DEBUG, "Received command: (0x%2.2X) 0x%4.4X", KEY_COMMAND, command); switch (command) { case KEY_COMMAND: /* pressing the escape command twice will pass it through */ return BRL_CMD_BLK(PASSDOTS) + translateInputCell(KEY_COMMAND); case KEY_COMMAND_SWITCHVT_PREV: return BRL_CMD_SWITCHVT_PREV; case KEY_COMMAND_SWITCHVT_NEXT: return BRL_CMD_SWITCHVT_NEXT; case KEY_COMMAND_SWITCHVT_1: return BRL_CMD_BLK(SWITCHVT) + 0; case KEY_COMMAND_SWITCHVT_2: return BRL_CMD_BLK(SWITCHVT) + 1; case KEY_COMMAND_SWITCHVT_3: return BRL_CMD_BLK(SWITCHVT) + 2; case KEY_COMMAND_SWITCHVT_4: return BRL_CMD_BLK(SWITCHVT) + 3; case KEY_COMMAND_SWITCHVT_5: return BRL_CMD_BLK(SWITCHVT) + 4; case KEY_COMMAND_SWITCHVT_6: return BRL_CMD_BLK(SWITCHVT) + 5; case KEY_COMMAND_SWITCHVT_7: return BRL_CMD_BLK(SWITCHVT) + 6; case KEY_COMMAND_SWITCHVT_8: return BRL_CMD_BLK(SWITCHVT) + 7; case KEY_COMMAND_SWITCHVT_9: return BRL_CMD_BLK(SWITCHVT) + 8; case KEY_COMMAND_SWITCHVT_10: return BRL_CMD_BLK(SWITCHVT) + 9; case KEY_COMMAND_PAGE_UP: return BRL_CMD_KEY(PAGE_UP); case KEY_COMMAND_PAGE_DOWN: return BRL_CMD_KEY(PAGE_DOWN); case KEY_COMMAND_PREFMENU: currentLine = 0; cursorRow = 0; cursorColumn = 31; sendCursorRow(); return BRL_CMD_PREFMENU; case KEY_COMMAND_PREFSAVE: return BRL_CMD_PREFSAVE; case KEY_COMMAND_PREFLOAD: return BRL_CMD_PREFLOAD; case KEY_COMMAND_FREEZE_ON: return BRL_CMD_FREEZE | BRL_FLG_TOGGLE_ON; case KEY_COMMAND_FREEZE_OFF: return BRL_CMD_FREEZE | BRL_FLG_TOGGLE_OFF; case KEY_COMMAND_RESTARTBRL: return BRL_CMD_RESTARTBRL; case KEY_COMMAND_DOWNLOAD: downloadFile(); break; default: logMessage(LOG_WARNING, "Unknown command: (0X%2.2X) 0X%4.4X", KEY_COMMAND, command); break; } break; } default: switch (key & KEY_MASK) { case KEY_UPDATE: handleUpdate(key >> KEY_SHIFT); break; case KEY_FUNCTION: logMessage(LOG_WARNING, "Unknown function: (0X%2.2X) 0X%4.4X", KEY_COMMAND, key>>KEY_SHIFT); break; default: { unsigned char dots = translateInputCell(key); logMessage(LOG_DEBUG, "Received character: 0X%2.2X dec=%d dots=%2.2X", key, key, dots); return BRL_CMD_BLK(PASSDOTS) + dots; } } break; } } return EOF; }
static void spk_flush (void) { asyncWait(spk_written * 1000 / CB_charactersPerSecond); spk_written = 0; }
static void handleTuneRequest_wait (int time) { asyncWait(time); }
static int brl_construct (BrailleDisplay *brl, char **parameters, const char *device) { if (!allocateCommandDescriptors()) return 0; inputLength = 0; inputStart = 0; inputEnd = 0; outputLength = 0; if (isQualifiedDevice(&device, "client")) { static const ModeEntry clientModeEntry = { #ifdef AF_LOCAL requestLocalConnection, #endif /* AF_LOCAL */ #ifdef __MINGW32__ requestNamedPipeConnection, #endif /* __MINGW32__ */ requestInetConnection }; mode = &clientModeEntry; } else if (isQualifiedDevice(&device, "server")) { static const ModeEntry serverModeEntry = { #ifdef AF_LOCAL acceptLocalConnection, #endif /* AF_LOCAL */ #ifdef __MINGW32__ acceptNamedPipeConnection, #endif /* __MINGW32__ */ acceptInetConnection }; mode = &serverModeEntry; } else { unsupportedDevice(device); goto failed; } if (!*device) device = VR_DEFAULT_SOCKET; #ifdef AF_LOCAL if (device[0] == '/') { struct sockaddr_un address; if (setLocalAddress(device, &address)) { fileDescriptor = mode->getLocalConnection(&address); } } else #endif /* AF_LOCAL */ #ifdef __MINGW32__ if (device[0] == '\\') { fileDescriptor = mode->getNamedPipeConnection(device); } else { static WSADATA wsadata; if (WSAStartup(MAKEWORD(1, 1), &wsadata)) { logWindowsSystemError("socket library start"); goto failed; } } #endif /* __MINGW32__ */ { struct sockaddr_in address; if (setInetAddress(device, &address)) { fileDescriptor = mode->getInetConnection(&address); } } if (fileDescriptor != -1) { char *line = NULL; while (1) { if (line) free(line); if ((line = readCommandLine())) { const char *word; logMessage(LOG_DEBUG, "command received: %s", line); if ((word = strtok(line, inputDelimiters))) { if (testWord(word, "cells")) { if (dimensionsChanged(brl)) { free(line); return 1; } } else if (testWord(word, "quit")) { break; } else { logMessage(LOG_WARNING, "unexpected command: %s", word); } } } else { asyncWait(1000); } } if (line) free(line); close(fileDescriptor); fileDescriptor = -1; } failed: deallocateCommandDescriptors(); return 0; }
int serialRestartDevice (SerialDevice *serial, unsigned int baud) { SerialLines highLines = 0; SerialLines lowLines = 0; int usingB0; #ifdef HAVE_POSIX_THREADS SerialFlowControlProc *flowControlProc = serial->pendingFlowControlProc; #endif /* HAVE_POSIX_THREADS */ if (serial->stream) { #if defined(GRUB_RUNTIME) #else /* clearerr() */ clearerr(serial->stream); #endif /* clear error on stdio stream */ } serialClearError(serial); if (!serialDiscardOutput(serial)) return 0; #ifdef HAVE_POSIX_THREADS serial->pendingFlowControlProc = NULL; #endif /* HAVE_POSIX_THREADS */ #ifdef B0 if (!serialPutSpeed(&serial->pendingAttributes, B0)) return 0; usingB0 = 1; #else /* B0 */ usingB0 = 0; #endif /* B0 */ if (!serialFlushAttributes(serial)) { if (!usingB0) return 0; if (!serialSetBaud(serial, baud)) return 0; if (!serialFlushAttributes(serial)) return 0; usingB0 = 0; } if (!usingB0) { SerialLines lines; if (!serialReadLines(serial, &lines)) return 0; { static const SerialLines linesTable[] = {SERIAL_LINE_DTR, SERIAL_LINE_RTS, 0}; const SerialLines *line = linesTable; while (*line) { *((lines & *line)? &highLines: &lowLines) |= *line; line += 1; } } if (highLines) if (!serialWriteLines(serial, 0, highLines|lowLines)) return 0; } asyncWait(SERIAL_DEVICE_RESTART_DELAY); if (!serialDiscardInput(serial)) return 0; if (!usingB0) if (!serialWriteLines(serial, highLines, lowLines)) return 0; #ifdef HAVE_POSIX_THREADS serial->pendingFlowControlProc = flowControlProc; #endif /* HAVE_POSIX_THREADS */ if (!serialSetBaud(serial, baud)) return 0; if (!serialFlushAttributes(serial)) return 0; return 1; }