mirror of
https://github.com/neovim/neovim.git
synced 2025-09-13 06:48:17 +00:00
Implement mch_delay
on top of libuv
Needed to temporarily move two static variables from os_unix.c to 'globals.h' as those are shared by other functions still in os_unix.
This commit is contained in:
@@ -9,6 +9,8 @@
|
|||||||
#ifndef NEOVIM_GLOBALS_H
|
#ifndef NEOVIM_GLOBALS_H
|
||||||
#define NEOVIM_GLOBALS_H
|
#define NEOVIM_GLOBALS_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "ex_eval.h"
|
#include "ex_eval.h"
|
||||||
#include "mbyte.h"
|
#include "mbyte.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
@@ -1131,6 +1133,12 @@ EXTERN FILE *time_fd INIT(= NULL); /* where to write startup timing */
|
|||||||
EXTERN int ignored;
|
EXTERN int ignored;
|
||||||
EXTERN char *ignoredp;
|
EXTERN char *ignoredp;
|
||||||
|
|
||||||
|
/* Temporarily moved these static variables to assist in migrating from
|
||||||
|
* os_unix.c */
|
||||||
|
EXTERN int curr_tmode INIT(= TMODE_COOK); /* contains current terminal mode */
|
||||||
|
/* volatile because it is used in signal handler deathtrap(). */
|
||||||
|
EXTERN volatile bool in_mch_delay INIT(= false); /* sleeping in mch_delay() */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Optional Farsi support. Include it here, so EXTERN and INIT are defined.
|
* Optional Farsi support. Include it here, so EXTERN and INIT are defined.
|
||||||
*/
|
*/
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include "misc1.h"
|
#include "misc1.h"
|
||||||
#include "misc2.h"
|
#include "misc2.h"
|
||||||
#include "os_unix.h"
|
#include "os/time.h"
|
||||||
#include "quickfix.h"
|
#include "quickfix.h"
|
||||||
#include "tag.h"
|
#include "tag.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
|
58
src/os/time.c
Normal file
58
src/os/time.c
Normal file
@@ -0,0 +1,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 mch_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_mch_delay = true;
|
||||||
|
old_tmode = curr_tmode;
|
||||||
|
|
||||||
|
if (curr_tmode == TMODE_RAW)
|
||||||
|
settmode(TMODE_SLEEP);
|
||||||
|
|
||||||
|
delay(ms);
|
||||||
|
|
||||||
|
settmode(old_tmode);
|
||||||
|
in_mch_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);
|
||||||
|
}
|
11
src/os/time.h
Normal file
11
src/os/time.h
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#ifndef NEOVIM_OS_TIME_H
|
||||||
|
#define NEOVIM_OS_TIME_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
void time_init(void);
|
||||||
|
void mch_delay(uint64_t ms, bool ignoreinput);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include "vim.h"
|
#include "vim.h"
|
||||||
#include "os_unix.h"
|
#include "os_unix.h"
|
||||||
|
#include "os/time.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "charset.h"
|
#include "charset.h"
|
||||||
#include "eval.h"
|
#include "eval.h"
|
||||||
@@ -47,6 +48,7 @@
|
|||||||
#include "term.h"
|
#include "term.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "os/os.h"
|
#include "os/os.h"
|
||||||
|
#include "os/time.h"
|
||||||
|
|
||||||
#include "os_unixx.h" /* unix includes for os_unix.c only */
|
#include "os_unixx.h" /* unix includes for os_unix.c only */
|
||||||
|
|
||||||
@@ -141,10 +143,6 @@ static char_u *extra_shell_arg = NULL;
|
|||||||
static int show_shell_mess = TRUE;
|
static int show_shell_mess = TRUE;
|
||||||
/* volatile because it is used in signal handler deathtrap(). */
|
/* volatile because it is used in signal handler deathtrap(). */
|
||||||
static volatile int deadly_signal = 0; /* The signal we caught */
|
static volatile int deadly_signal = 0; /* The signal we caught */
|
||||||
/* volatile because it is used in signal handler deathtrap(). */
|
|
||||||
static volatile int in_mch_delay = FALSE; /* sleeping in mch_delay() */
|
|
||||||
|
|
||||||
static int curr_tmode = TMODE_COOK; /* contains current terminal mode */
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef SYS_SIGLIST_DECLARED
|
#ifdef SYS_SIGLIST_DECLARED
|
||||||
@@ -341,64 +339,6 @@ int mch_char_avail()
|
|||||||
return WaitForChar(0L);
|
return WaitForChar(0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mch_delay(long msec, int 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_mch_delay = TRUE;
|
|
||||||
old_tmode = curr_tmode;
|
|
||||||
if (curr_tmode == TMODE_RAW)
|
|
||||||
settmode(TMODE_SLEEP);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Everybody sleeps in a different way...
|
|
||||||
* Prefer nanosleep(), some versions of usleep() can only sleep up to
|
|
||||||
* one second.
|
|
||||||
*/
|
|
||||||
#ifdef HAVE_NANOSLEEP
|
|
||||||
{
|
|
||||||
struct timespec ts;
|
|
||||||
|
|
||||||
ts.tv_sec = msec / 1000;
|
|
||||||
ts.tv_nsec = (msec % 1000) * 1000000;
|
|
||||||
(void)nanosleep(&ts, NULL);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
# ifdef HAVE_USLEEP
|
|
||||||
while (msec >= 1000) {
|
|
||||||
usleep((unsigned int)(999 * 1000));
|
|
||||||
msec -= 999;
|
|
||||||
}
|
|
||||||
usleep((unsigned int)(msec * 1000));
|
|
||||||
# else
|
|
||||||
# ifndef HAVE_SELECT
|
|
||||||
poll(NULL, 0, (int)msec);
|
|
||||||
# else
|
|
||||||
{
|
|
||||||
struct timeval tv;
|
|
||||||
|
|
||||||
tv.tv_sec = msec / 1000;
|
|
||||||
tv.tv_usec = (msec % 1000) * 1000;
|
|
||||||
/*
|
|
||||||
* NOTE: Solaris 2.6 has a bug that makes select() hang here. Get
|
|
||||||
* a patch from Sun to fix this. Reported by Gunnar Pedersen.
|
|
||||||
*/
|
|
||||||
select(0, NULL, NULL, NULL, &tv);
|
|
||||||
}
|
|
||||||
# endif /* HAVE_SELECT */
|
|
||||||
# endif /* HAVE_NANOSLEEP */
|
|
||||||
#endif /* HAVE_USLEEP */
|
|
||||||
|
|
||||||
settmode(old_tmode);
|
|
||||||
in_mch_delay = FALSE;
|
|
||||||
} else
|
|
||||||
WaitForChar(msec);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(HAVE_SIGALTSTACK) || defined(HAVE_SIGSTACK)
|
#if defined(HAVE_SIGALTSTACK) || defined(HAVE_SIGSTACK)
|
||||||
/*
|
/*
|
||||||
* Support for using the signal stack.
|
* Support for using the signal stack.
|
||||||
@@ -1307,6 +1247,8 @@ void mch_early_init()
|
|||||||
signal_stack = (char *)alloc(SIGSTKSZ);
|
signal_stack = (char *)alloc(SIGSTKSZ);
|
||||||
init_signal_stack();
|
init_signal_stack();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
time_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(EXITFREE) || defined(PROTO)
|
#if defined(EXITFREE) || defined(PROTO)
|
||||||
|
@@ -4,7 +4,6 @@
|
|||||||
void mch_write(char_u *s, int len);
|
void mch_write(char_u *s, int len);
|
||||||
int mch_inchar(char_u *buf, int maxlen, long wtime, int tb_change_cnt);
|
int mch_inchar(char_u *buf, int maxlen, long wtime, int tb_change_cnt);
|
||||||
int mch_char_avail(void);
|
int mch_char_avail(void);
|
||||||
void mch_delay(long msec, int ignoreinput);
|
|
||||||
void mch_startjmp(void);
|
void mch_startjmp(void);
|
||||||
void mch_endjmp(void);
|
void mch_endjmp(void);
|
||||||
void mch_didjmp(void);
|
void mch_didjmp(void);
|
||||||
|
@@ -46,6 +46,7 @@
|
|||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
#include "os/os.h"
|
#include "os/os.h"
|
||||||
|
#include "os/time.h"
|
||||||
|
|
||||||
#ifdef HAVE_TGETENT
|
#ifdef HAVE_TGETENT
|
||||||
# ifdef HAVE_TERMIOS_H
|
# ifdef HAVE_TERMIOS_H
|
||||||
|
1
src/ui.c
1
src/ui.c
@@ -30,6 +30,7 @@
|
|||||||
#include "normal.h"
|
#include "normal.h"
|
||||||
#include "option.h"
|
#include "option.h"
|
||||||
#include "os_unix.h"
|
#include "os_unix.h"
|
||||||
|
#include "os/time.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "term.h"
|
#include "term.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
15
test/unit/os/time.moon
Normal file
15
test/unit/os/time.moon
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{time: lua_time} = require 'os'
|
||||||
|
{:cimport, :eq} = require 'test.unit.helpers'
|
||||||
|
|
||||||
|
time = cimport './src/os/time.h'
|
||||||
|
|
||||||
|
describe 'time function', ->
|
||||||
|
describe 'mch_delay', ->
|
||||||
|
mch_delay = (ms) ->
|
||||||
|
time.mch_delay ms, false
|
||||||
|
|
||||||
|
it 'sleeps at least the number of requested milliseconds', ->
|
||||||
|
curtime = lua_time!
|
||||||
|
mch_delay 1000
|
||||||
|
ellapsed = lua_time! - curtime
|
||||||
|
eq true, ellapsed >= 1 and ellapsed <=2
|
Reference in New Issue
Block a user