Mercurial > vim
comparison src/channel.c @ 9058:87c2e43a4a12 v7.4.1814
commit https://github.com/vim/vim/commit/b8d4905592fc26fcd09180d7d6bfefd899f2f6c6
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun May 1 14:22:16 2016 +0200
patch 7.4.1814
Problem: A channel may be garbage collected while it's still being used by
a job. (James McCoy)
Solution: Mark the channel as used if the job is still used. Do the same
for channels that are still used.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sun, 01 May 2016 14:30:06 +0200 |
parents | 31bba6f25d84 |
children | a86103d4b356 |
comparison
equal
deleted
inserted
replaced
9057:93d6f07403ae | 9058:87c2e43a4a12 |
---|---|
3551 int | 3551 int |
3552 set_ref_in_channel(int copyID) | 3552 set_ref_in_channel(int copyID) |
3553 { | 3553 { |
3554 int abort = FALSE; | 3554 int abort = FALSE; |
3555 channel_T *channel; | 3555 channel_T *channel; |
3556 int part; | 3556 typval_T tv; |
3557 | 3557 |
3558 for (channel = first_channel; channel != NULL; channel = channel->ch_next) | 3558 for (channel = first_channel; channel != NULL; channel = channel->ch_next) |
3559 { | 3559 if (channel_still_useful(channel)) |
3560 for (part = PART_SOCK; part < PART_IN; ++part) | 3560 { |
3561 { | 3561 tv.v_type = VAR_CHANNEL; |
3562 jsonq_T *head = &channel->ch_part[part].ch_json_head; | 3562 tv.vval.v_channel = channel; |
3563 jsonq_T *item = head->jq_next; | 3563 abort = abort || set_ref_in_item(&tv, copyID, NULL, NULL); |
3564 | 3564 } |
3565 while (item != NULL) | |
3566 { | |
3567 list_T *l = item->jq_value->vval.v_list; | |
3568 | |
3569 if (l->lv_copyID != copyID) | |
3570 { | |
3571 l->lv_copyID = copyID; | |
3572 abort = abort || set_ref_in_list(l, copyID, NULL); | |
3573 } | |
3574 item = item->jq_next; | |
3575 } | |
3576 } | |
3577 } | |
3578 return abort; | 3565 return abort; |
3579 } | 3566 } |
3580 | 3567 |
3581 /* | 3568 /* |
3582 * Return the "part" to write to for "channel". | 3569 * Return the "part" to write to for "channel". |
4090 && (job->jv_stoponexit != NULL || job->jv_exit_cb != NULL | 4077 && (job->jv_stoponexit != NULL || job->jv_exit_cb != NULL |
4091 || (job->jv_channel != NULL | 4078 || (job->jv_channel != NULL |
4092 && channel_still_useful(job->jv_channel))); | 4079 && channel_still_useful(job->jv_channel))); |
4093 } | 4080 } |
4094 | 4081 |
4082 /* | |
4083 * Mark references in jobs that are still useful. | |
4084 */ | |
4085 int | |
4086 set_ref_in_job(int copyID) | |
4087 { | |
4088 int abort = FALSE; | |
4089 job_T *job; | |
4090 typval_T tv; | |
4091 | |
4092 for (job = first_job; job != NULL; job = job->jv_next) | |
4093 if (job_still_useful(job)) | |
4094 { | |
4095 tv.v_type = VAR_JOB; | |
4096 tv.vval.v_job = job; | |
4097 abort = abort || set_ref_in_item(&tv, copyID, NULL, NULL); | |
4098 } | |
4099 return abort; | |
4100 } | |
4101 | |
4095 void | 4102 void |
4096 job_unref(job_T *job) | 4103 job_unref(job_T *job) |
4097 { | 4104 { |
4098 if (job != NULL && --job->jv_refcount <= 0) | 4105 if (job != NULL && --job->jv_refcount <= 0) |
4099 { | 4106 { |