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;