comparison src/channel.c @ 8074:dc32c8026899 v7.4.1331

commit https://github.com/vim/vim/commit/d46ae142aa9452e99576b5e923de974704e3c896 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Feb 16 13:33:52 2016 +0100 patch 7.4.1331 Problem: Crash when closing the channel in a callback. (Christian J. Robinson) Solution: Take the callback out of the list before invoking it.
author Christian Brabandt <cb@256bit.org>
date Tue, 16 Feb 2016 13:45:04 +0100
parents 38887bf423ba
children b6cb94ad97a4
comparison
equal deleted inserted replaced
8073:42db5fe07958 8074:dc32c8026899
886 vim_free(reader.js_buf); 886 vim_free(reader.js_buf);
887 return ret; 887 return ret;
888 } 888 }
889 889
890 /* 890 /*
891 * Remove "node" from the queue that it is in and free it. 891 * Remove "node" from the queue that it is in. Does not free it.
892 * Also frees the contained callback name.
893 */ 892 */
894 static void 893 static void
895 remove_cb_node(cbq_T *head, cbq_T *node) 894 remove_cb_node(cbq_T *head, cbq_T *node)
896 { 895 {
897 if (node->cq_prev == NULL) 896 if (node->cq_prev == NULL)
900 node->cq_prev->cq_next = node->cq_next; 899 node->cq_prev->cq_next = node->cq_next;
901 if (node->cq_next == NULL) 900 if (node->cq_next == NULL)
902 head->cq_prev = node->cq_prev; 901 head->cq_prev = node->cq_prev;
903 else 902 else
904 node->cq_next->cq_prev = node->cq_prev; 903 node->cq_next->cq_prev = node->cq_prev;
905 vim_free(node->cq_callback);
906 vim_free(node);
907 } 904 }
908 905
909 /* 906 /*
910 * Remove "node" from the queue that it is in and free it. 907 * Remove "node" from the queue that it is in and free it.
911 * Caller should have freed or used node->jq_value. 908 * Caller should have freed or used node->jq_value.
1142 while (item != NULL) 1139 while (item != NULL)
1143 { 1140 {
1144 if (item->cq_seq_nr == seq_nr) 1141 if (item->cq_seq_nr == seq_nr)
1145 { 1142 {
1146 ch_log(channel, "Invoking one-time callback\n"); 1143 ch_log(channel, "Invoking one-time callback\n");
1144 /* Remove the item from the list first, if the callback
1145 * invokes ch_close() the list will be cleared. */
1146 remove_cb_node(head, item);
1147 invoke_callback(channel, item->cq_callback, argv); 1147 invoke_callback(channel, item->cq_callback, argv);
1148 remove_cb_node(head, item); 1148 vim_free(item->cq_callback);
1149 vim_free(item);
1149 done = TRUE; 1150 done = TRUE;
1150 break; 1151 break;
1151 } 1152 }
1152 item = item->cq_next; 1153 item = item->cq_next;
1153 } 1154 }
1327 1328
1328 while (channel_peek(channel) != NULL) 1329 while (channel_peek(channel) != NULL)
1329 vim_free(channel_get(channel)); 1330 vim_free(channel_get(channel));
1330 1331
1331 while (cb_head->cq_next != NULL) 1332 while (cb_head->cq_next != NULL)
1332 remove_cb_node(cb_head, cb_head->cq_next); 1333 {
1334 cbq_T *node = cb_head->cq_next;
1335
1336 remove_cb_node(cb_head, node);
1337 vim_free(node->cq_callback);
1338 vim_free(node);
1339 }
1333 1340
1334 while (json_head->jq_next != NULL) 1341 while (json_head->jq_next != NULL)
1335 { 1342 {
1336 free_tv(json_head->jq_next->jq_value); 1343 free_tv(json_head->jq_next->jq_value);
1337 remove_json_node(json_head, json_head->jq_next); 1344 remove_json_node(json_head, json_head->jq_next);