Mercurial > vim
comparison src/eval.c @ 8310:aec8f8ce8e4c v7.4.1447
commit https://github.com/vim/vim/commit/d6051b5eb83687f60bb4a2f3d5cd23fe8b290eb4
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Feb 28 15:49:03 2016 +0100
patch 7.4.1447
Problem: Memory leak when using ch_read(). (Dominique Pelle)
No log message when stopping a job and a few other situations.
Too many "Nothing to read" messages. Channels are not freed.
Solution: Free the listtv. Add more log messages. Remove "Nothing to read"
message. Remove the channel from the job when its refcount
becomes zero.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sun, 28 Feb 2016 16:00:05 +0100 |
parents | 18fd94bd4eb8 |
children | 4e057409f1d7 |
comparison
equal
deleted
inserted
replaced
8309:9df48ab0f290 | 8310:aec8f8ce8e4c |
---|---|
7739 | 7739 |
7740 #if defined(FEAT_CHANNEL) || defined(PROTO) | 7740 #if defined(FEAT_CHANNEL) || defined(PROTO) |
7741 /* | 7741 /* |
7742 * Decrement the reference count on "channel" and maybe free it when it goes | 7742 * Decrement the reference count on "channel" and maybe free it when it goes |
7743 * down to zero. Don't free it if there is a pending action. | 7743 * down to zero. Don't free it if there is a pending action. |
7744 * Returns TRUE when the channel was freed. | 7744 * Returns TRUE when the channel is no longer referenced. |
7745 */ | 7745 */ |
7746 int | 7746 int |
7747 channel_unref(channel_T *channel) | 7747 channel_unref(channel_T *channel) |
7748 { | 7748 { |
7749 if (channel != NULL && --channel->ch_refcount <= 0) | 7749 if (channel != NULL && --channel->ch_refcount <= 0) |
7760 | 7760 |
7761 static void | 7761 static void |
7762 job_free(job_T *job) | 7762 job_free(job_T *job) |
7763 { | 7763 { |
7764 # ifdef FEAT_CHANNEL | 7764 # ifdef FEAT_CHANNEL |
7765 ch_log(job->jv_channel, "Freeing job"); | |
7765 if (job->jv_channel != NULL) | 7766 if (job->jv_channel != NULL) |
7766 { | 7767 { |
7767 /* The link from the channel to the job doesn't count as a reference, | 7768 /* The link from the channel to the job doesn't count as a reference, |
7768 * thus don't decrement the refcount of the job. The reference from | 7769 * thus don't decrement the refcount of the job. The reference from |
7769 * the job to the channel does count the refrence, decrement it and | 7770 * the job to the channel does count the refrence, decrement it and |
7794 { | 7795 { |
7795 /* Do not free the job when it has not ended yet and there is a | 7796 /* Do not free the job when it has not ended yet and there is a |
7796 * "stoponexit" flag or an exit callback. */ | 7797 * "stoponexit" flag or an exit callback. */ |
7797 if (job->jv_status != JOB_STARTED | 7798 if (job->jv_status != JOB_STARTED |
7798 || (job->jv_stoponexit == NULL && job->jv_exit_cb == NULL)) | 7799 || (job->jv_stoponexit == NULL && job->jv_exit_cb == NULL)) |
7800 { | |
7799 job_free(job); | 7801 job_free(job); |
7802 } | |
7803 else if (job->jv_channel != NULL) | |
7804 { | |
7805 /* Do remove the link to the channel, otherwise it hangs | |
7806 * around until Vim exits. See job_free() for refcount. */ | |
7807 job->jv_channel->ch_job = NULL; | |
7808 channel_unref(job->jv_channel); | |
7809 job->jv_channel = NULL; | |
7810 } | |
7800 } | 7811 } |
7801 } | 7812 } |
7802 | 7813 |
7803 /* | 7814 /* |
7804 * Allocate a job. Sets the refcount to one and sets options default. | 7815 * Allocate a job. Sets the refcount to one and sets options default. |
10465 { | 10476 { |
10466 if (opt.jo_set & JO_ID) | 10477 if (opt.jo_set & JO_ID) |
10467 id = opt.jo_id; | 10478 id = opt.jo_id; |
10468 channel_read_json_block(channel, part, timeout, id, &listtv); | 10479 channel_read_json_block(channel, part, timeout, id, &listtv); |
10469 if (listtv != NULL) | 10480 if (listtv != NULL) |
10481 { | |
10470 *rettv = *listtv; | 10482 *rettv = *listtv; |
10483 vim_free(listtv); | |
10484 } | |
10471 else | 10485 else |
10472 { | 10486 { |
10473 rettv->v_type = VAR_SPECIAL; | 10487 rettv->v_type = VAR_SPECIAL; |
10474 rettv->vval.v_number = VVAL_NONE; | 10488 rettv->vval.v_number = VVAL_NONE; |
10475 } | 10489 } |
15290 { | 15304 { |
15291 EMSG(_(e_invarg)); | 15305 EMSG(_(e_invarg)); |
15292 return; | 15306 return; |
15293 } | 15307 } |
15294 } | 15308 } |
15309 # ifdef FEAT_CHANNEL | |
15310 ch_logs(job->jv_channel, "Stopping job with '%s'", (char *)arg); | |
15311 # endif | |
15295 if (mch_stop_job(job, arg) == FAIL) | 15312 if (mch_stop_job(job, arg) == FAIL) |
15296 rettv->vval.v_number = 0; | 15313 rettv->vval.v_number = 0; |
15297 else | 15314 else |
15298 { | 15315 { |
15299 rettv->vval.v_number = 1; | 15316 rettv->vval.v_number = 1; |