aboutsummaryrefslogtreecommitdiff
path: root/src/os/time.c
blob: c0436595f66f79cb59286b0c638318c1fd7fb518 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <stdint.h>
#include <stdbool.h>

#include <uv.h>

#include "vim.h"
#include "term.h"

static uv_mutex_t delay_mutex;
static uv_cond_t delay_cond;

static void delay(uint64_t ms);

void time_init()
{
  uv_mutex_init(&delay_mutex);
  uv_cond_init(&delay_cond);
}

void os_delay(uint64_t ms, bool ignoreinput)
{
  int old_tmode;

  if (ignoreinput) {
    // Go to cooked mode without echo, to allow SIGINT interrupting us
    // here.  But we don't want QUIT to kill us (CTRL-\ used in a
    // shell may produce SIGQUIT).
    in_os_delay = true;
    old_tmode = curr_tmode;

    if (curr_tmode == TMODE_RAW)
      settmode(TMODE_SLEEP);

    delay(ms);

    settmode(old_tmode);
    in_os_delay = false;
  } else {
    delay(ms);
  }
}

static void delay(uint64_t ms)
{
  uint64_t hrtime;
  int64_t ns = ms * 1000000;  // convert to nanoseconds

  uv_mutex_lock(&delay_mutex);

  while (ns > 0) {
    hrtime =  uv_hrtime();
    if (uv_cond_timedwait(&delay_cond, &delay_mutex, ns) == UV_ETIMEDOUT)
      break;
    ns -= uv_hrtime() - hrtime;
  }

  uv_mutex_unlock(&delay_mutex);
}