0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

patch 7.4.1398

Problem:    The close-cb option is not implemented yet.
Solution:   Implemente close-cb. (Yasuhiro Matsumoto)
This commit is contained in:
Bram Moolenaar
2016-02-23 13:20:22 +01:00
parent 0bb6108eb4
commit 4e221c99e8
7 changed files with 116 additions and 30 deletions

View File

@@ -485,7 +485,11 @@ static char *e_cannot_connect = N_("E902: Cannot connect to port");
* Returns NULL for failure.
*/
channel_T *
channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void))
channel_open(
char *hostname,
int port_in,
int waittime,
void (*nb_close_cb)(void))
{
int sd = -1;
struct sockaddr_in server;
@@ -711,7 +715,7 @@ channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void))
}
channel->CH_SOCK_FD = (sock_T)sd;
channel->ch_close_cb = close_cb;
channel->ch_nb_close_cb = nb_close_cb;
#ifdef FEAT_GUI
channel_gui_register(channel);
@@ -790,6 +794,15 @@ channel_set_options(channel_T *channel, jobopt_T *opt)
else
*cbp = NULL;
}
if (opt->jo_set & JO_CLOSE_CALLBACK)
{
cbp = &channel->ch_close_cb;
vim_free(*cbp);
if (opt->jo_close_cb != NULL && *opt->jo_close_cb != NUL)
*cbp = vim_strsave(opt->jo_close_cb);
else
*cbp = NULL;
}
}
/*
@@ -1255,7 +1268,7 @@ may_invoke_callback(channel_T *channel, int part)
ch_mode_T ch_mode = channel->ch_part[part].ch_mode;
char_u *callback = NULL;
if (channel->ch_close_cb != NULL)
if (channel->ch_nb_close_cb != NULL)
/* this channel is handled elsewhere (netbeans) */
return FALSE;
@@ -1477,7 +1490,28 @@ channel_close(channel_T *channel)
}
#endif
channel->ch_close_cb = NULL;
if (channel->ch_close_cb != NULL)
{
typval_T argv[1];
typval_T rettv;
int dummy;
/* invoke the close callback; increment the refcount to avoid it
* being freed halfway */
argv[0].v_type = VAR_CHANNEL;
argv[0].vval.v_channel = channel;
++channel->ch_refcount;
call_func(channel->ch_close_cb, (int)STRLEN(channel->ch_close_cb),
&rettv, 1, argv, 0L, 0L, &dummy, TRUE, NULL);
clear_tv(&rettv);
--channel->ch_refcount;
/* the callback is only called once */
vim_free(channel->ch_close_cb);
channel->ch_close_cb = NULL;
}
channel->ch_nb_close_cb = NULL;
channel_clear(channel);
}
@@ -1539,6 +1573,8 @@ channel_clear(channel_T *channel)
#endif
vim_free(channel->ch_callback);
channel->ch_callback = NULL;
vim_free(channel->ch_close_cb);
channel->ch_close_cb = NULL;
}
#if defined(EXITFREE) || defined(PROTO)
@@ -1732,8 +1768,8 @@ channel_read(channel_T *channel, int part, char *func)
* keep stdin and stderr open? Probably not, assume the other side
* has died. */
channel_close(channel);
if (channel->ch_close_cb != NULL)
(*channel->ch_close_cb)();
if (channel->ch_nb_close_cb != NULL)
(*channel->ch_nb_close_cb)();
if (len < 0)
{

View File

@@ -10067,6 +10067,18 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported)
return FAIL;
}
}
else if (STRCMP(hi->hi_key, "close-cb") == 0)
{
if (!(supported & JO_CLOSE_CALLBACK))
break;
opt->jo_set |= JO_CLOSE_CALLBACK;
opt->jo_close_cb = get_callback(item);
if (opt->jo_close_cb == NULL)
{
EMSG2(_(e_invarg2), "close-cb");
return FAIL;
}
}
else if (STRCMP(hi->hi_key, "waittime") == 0)
{
if (!(supported & JO_WAITTIME))
@@ -18924,7 +18936,7 @@ item_compare2(const void *s1, const void *s2)
rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */
res = call_func(sortinfo->item_compare_func,
(int)STRLEN(sortinfo->item_compare_func),
(int)STRLEN(sortinfo->item_compare_func),
&rettv, 2, argv, 0L, 0L, &dummy, TRUE,
sortinfo->item_compare_selfdict);
clear_tv(&argv[0]);

View File

@@ -7,10 +7,10 @@ channel_T *add_channel(void);
void channel_free(channel_T *channel);
void channel_gui_register(channel_T *channel);
void channel_gui_register_all(void);
channel_T *channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void));
channel_T *channel_open(char *hostname, int port_in, int waittime, void (*nb_close_cb)(void));
void channel_set_pipes(channel_T *channel, sock_T in, sock_T out, sock_T err);
void channel_set_job(channel_T *channel, job_T *job);
void channel_set_options(channel_T *channel, jobopt_T *options);
void channel_set_options(channel_T *channel, jobopt_T *opt);
void channel_set_req_callback(channel_T *channel, int part, char_u *callback, int id);
char_u *channel_get(channel_T *channel, int part);
int channel_collapse(channel_T *channel, int part);

View File

@@ -1366,9 +1366,12 @@ struct channel_S {
* first error until the connection works
* again. */
void (*ch_close_cb)(void); /* callback for when channel is closed */
void (*ch_nb_close_cb)(void);
/* callback for Netbeans when channel is
* closed */
char_u *ch_callback; /* call when any msg is not handled */
char_u *ch_close_cb; /* call when channel is closed */
job_T *ch_job; /* Job that uses this channel; this does not
* count as a reference to avoid a circular
@@ -1377,25 +1380,27 @@ struct channel_S {
int ch_refcount; /* reference count */
};
#define JO_MODE 0x0001 /* channel mode */
#define JO_IN_MODE 0x0002 /* stdin mode */
#define JO_OUT_MODE 0x0004 /* stdout mode */
#define JO_ERR_MODE 0x0008 /* stderr mode */
#define JO_CALLBACK 0x0010 /* channel callback */
#define JO_OUT_CALLBACK 0x0020 /* stdout callback */
#define JO_ERR_CALLBACK 0x0040 /* stderr callback */
#define JO_WAITTIME 0x0080 /* only for ch_open() */
#define JO_TIMEOUT 0x0100 /* all timeouts */
#define JO_OUT_TIMEOUT 0x0200 /* stdout timeouts */
#define JO_ERR_TIMEOUT 0x0400 /* stderr timeouts */
#define JO_PART 0x0800 /* "part" */
#define JO_ID 0x1000 /* "id" */
#define JO_STOPONEXIT 0x2000 /* "stoponexit" */
#define JO_EXIT_CB 0x4000 /* "exit-cb" */
#define JO_ALL 0xffffff
#define JO_MODE 0x0001 /* channel mode */
#define JO_IN_MODE 0x0002 /* stdin mode */
#define JO_OUT_MODE 0x0004 /* stdout mode */
#define JO_ERR_MODE 0x0008 /* stderr mode */
#define JO_CALLBACK 0x0010 /* channel callback */
#define JO_OUT_CALLBACK 0x0020 /* stdout callback */
#define JO_ERR_CALLBACK 0x0040 /* stderr callback */
#define JO_CLOSE_CALLBACK 0x0080 /* close callback */
#define JO_WAITTIME 0x0100 /* only for ch_open() */
#define JO_TIMEOUT 0x0200 /* all timeouts */
#define JO_OUT_TIMEOUT 0x0400 /* stdout timeouts */
#define JO_ERR_TIMEOUT 0x0800 /* stderr timeouts */
#define JO_PART 0x1000 /* "part" */
#define JO_ID 0x2000 /* "id" */
#define JO_STOPONEXIT 0x4000 /* "stoponexit" */
#define JO_EXIT_CB 0x8000 /* "exit-cb" */
#define JO_ALL 0xffffff
#define JO_MODE_ALL (JO_MODE + JO_IN_MODE + JO_OUT_MODE + JO_ERR_MODE)
#define JO_CB_ALL (JO_CALLBACK + JO_OUT_CALLBACK + JO_ERR_CALLBACK)
#define JO_CB_ALL \
(JO_CALLBACK + JO_OUT_CALLBACK + JO_ERR_CALLBACK + JO_CLOSE_CALLBACK)
#define JO_TIMEOUT_ALL (JO_TIMEOUT + JO_OUT_TIMEOUT + JO_ERR_TIMEOUT)
/*
@@ -1412,6 +1417,7 @@ typedef struct
char_u *jo_callback; /* not allocated! */
char_u *jo_out_cb; /* not allocated! */
char_u *jo_err_cb; /* not allocated! */
char_u *jo_close_cb; /* not allocated! */
int jo_waittime;
int jo_timeout;
int jo_out_timeout;

View File

@@ -140,6 +140,10 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
print("sending: {}".format(cmd))
self.request.sendall(cmd.encode('utf-8'))
response = ""
elif decoded[1] == 'close me':
print("closing")
self.request.close()
response = ""
elif decoded[1] == 'wait a bit':
time.sleep(0.2)
response = "waited"

View File

@@ -471,9 +471,9 @@ endfunc
"""""""""
let s:job_ret = 'not yet'
let s:job_exit_ret = 'not yet'
function MyExitCb(job, status)
let s:job_ret = 'done'
let s:job_exit_ret = 'done'
endfunc
function s:test_exit_callback(port)
@@ -490,6 +490,32 @@ func Test_exit_callback()
" calling job_status() triggers the callback
call job_status(s:exit_job)
call assert_equal('done', s:job_ret)
call assert_equal('done', s:job_exit_ret)
endif
endfunc
"""""""""
let s:ch_close_ret = 'alive'
function MyCloseCb(ch)
let s:ch_close_ret = 'closed'
endfunc
function s:test_close_callback(port)
let handle = ch_open('localhost:' . a:port, s:chopt)
if ch_status(handle) == "fail"
call assert_false(1, "Can't open channel")
return
endif
call ch_setoptions(handle, {'close-cb': 'MyCloseCb'})
call assert_equal('', ch_sendexpr(handle, 'close me'))
sleep 20m
call assert_equal('closed', s:ch_close_ret)
endfunc
func Test_close_callback()
call ch_log('Test_close_callback()')
call s:run_server('s:test_close_callback')
endfunc

View File

@@ -748,6 +748,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1398,
/**/
1397,
/**/