0
0
mirror of https://github.com/vim/vim.git synced 2025-09-24 03:44:06 -04:00

patch 7.4.1855

Problem:    Valgrind reports memory leak for job that is not freed.
Solution:   Free all jobs on exit.  Add test for failing job.
This commit is contained in:
Bram Moolenaar
2016-05-28 22:22:34 +02:00
parent d80629cef0
commit 655da31a18
5 changed files with 32 additions and 4 deletions

View File

@@ -1285,6 +1285,7 @@ write_buf_line(buf_T *buf, linenr_T lnum, channel_T *channel)
int len = (int)STRLEN(line); int len = (int)STRLEN(line);
char_u *p; char_u *p;
/* Need to make a copy to be able to append a NL. */
if ((p = alloc(len + 2)) == NULL) if ((p = alloc(len + 2)) == NULL)
return; return;
STRCPY(p, line); STRCPY(p, line);
@@ -2888,7 +2889,7 @@ channel_close_now(channel_T *channel)
/* /*
* Read from channel "channel" for as long as there is something to read. * Read from channel "channel" for as long as there is something to read.
* "part" is PART_SOCK, PART_OUT or PART_ERR. * "part" is PART_SOCK, PART_OUT or PART_ERR.
* The data is put in the read queue. * The data is put in the read queue. No callbacks are invoked here.
*/ */
static void static void
channel_read(channel_T *channel, int part, char *func) channel_read(channel_T *channel, int part, char *func)
@@ -4184,6 +4185,15 @@ job_free(job_T *job)
} }
} }
#if defined(EXITFREE) || defined(PROTO)
void
job_free_all(void)
{
while (first_job != NULL)
job_free(first_job);
}
#endif
/* /*
* Return TRUE if the job should not be freed yet. Do not free the job when * Return TRUE if the job should not be freed yet. Do not free the job when
* it has not ended yet and there is a "stoponexit" flag, an exit callback * it has not ended yet and there is a "stoponexit" flag, an exit callback

View File

@@ -1126,9 +1126,6 @@ free_all_mem(void)
# endif # endif
# ifdef FEAT_DIFF # ifdef FEAT_DIFF
diff_clear(curtab); diff_clear(curtab);
# endif
# ifdef FEAT_JOB_CHANNEL
channel_free_all();
# endif # endif
clear_sb_text(); /* free any scrollback text */ clear_sb_text(); /* free any scrollback text */
@@ -1221,6 +1218,10 @@ free_all_mem(void)
# ifdef FEAT_EVAL # ifdef FEAT_EVAL
eval_clear(); eval_clear();
# endif # endif
# ifdef FEAT_JOB_CHANNEL
channel_free_all();
job_free_all();
# endif
free_termoptions(); free_termoptions();

View File

@@ -50,6 +50,7 @@ void clear_job_options(jobopt_T *opt);
void free_job_options(jobopt_T *opt); void free_job_options(jobopt_T *opt);
int get_job_options(typval_T *tv, jobopt_T *opt, int supported); int get_job_options(typval_T *tv, jobopt_T *opt, int supported);
channel_T *get_channel_arg(typval_T *tv, int check_open, int reading, int part); channel_T *get_channel_arg(typval_T *tv, int check_open, int reading, int part);
void job_free_all(void);
int set_ref_in_job(int copyID); int set_ref_in_job(int copyID);
void job_unref(job_T *job); void job_unref(job_T *job);
int free_unused_jobs_contents(int copyID, int mask); int free_unused_jobs_contents(int copyID, int mask);

View File

@@ -250,6 +250,20 @@ func Test_cycle_partial_job()
endif endif
endfunc endfunc
func Test_job_start_fails()
if has('job')
let job = job_start('axdfxsdf')
for i in range(100)
if job_status(job) == 'dead'
break
endif
sleep 10m
endfor
call assert_equal('dead', job_status(job))
unlet job
endif
endfunc
func Test_ref_job_partial_dict() func Test_ref_job_partial_dict()
if has('job') if has('job')
let g:ref_job = job_start('echo') let g:ref_job = job_start('echo')

View File

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