Mercurial > vim
comparison src/netbeans.c @ 2639:73dd10c18ec4 v7.3.060
updated for version 7.3.060
Problem: Netbeans: crash when socket is disconnected unexpectedly.
Solution: Don't cleanup when a read fails, put a message in the queue and
disconnect later. (Xavier de Gaye)
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Tue, 16 Nov 2010 15:49:02 +0100 |
parents | 75a89c7c204e |
children | ac04f392ba48 |
comparison
equal
deleted
inserted
replaced
2638:75a89c7c204e | 2639:73dd10c18ec4 |
---|---|
133 #endif | 133 #endif |
134 | 134 |
135 static int needupdate = 0; | 135 static int needupdate = 0; |
136 static int inAtomic = 0; | 136 static int inAtomic = 0; |
137 | 137 |
138 /* | |
139 * Close the socket and remove the input handlers. | |
140 */ | |
138 static void | 141 static void |
139 netbeans_close(void) | 142 nb_close_socket(void) |
140 { | 143 { |
141 if (!NETBEANS_OPEN) | |
142 return; | |
143 | |
144 netbeans_send_disconnect(); | |
145 | |
146 #ifdef FEAT_GUI_X11 | 144 #ifdef FEAT_GUI_X11 |
147 if (inputHandler != (XtInputId)NULL) | 145 if (inputHandler != (XtInputId)NULL) |
148 { | 146 { |
149 XtRemoveInput(inputHandler); | 147 XtRemoveInput(inputHandler); |
150 inputHandler = (XtInputId)NULL; | 148 inputHandler = (XtInputId)NULL; |
165 } | 163 } |
166 # endif | 164 # endif |
167 # endif | 165 # endif |
168 #endif | 166 #endif |
169 | 167 |
168 sock_close(nbsock); | |
169 nbsock = -1; | |
170 } | |
171 | |
172 /* | |
173 * Close the connection and cleanup. | |
174 * May be called when nb_close_socket() was called earlier. | |
175 */ | |
176 static void | |
177 netbeans_close(void) | |
178 { | |
179 if (NETBEANS_OPEN) | |
180 { | |
181 netbeans_send_disconnect(); | |
182 nb_close_socket(); | |
183 } | |
184 | |
170 #ifdef FEAT_BEVAL | 185 #ifdef FEAT_BEVAL |
171 bevalServers &= ~BEVAL_NETBEANS; | 186 bevalServers &= ~BEVAL_NETBEANS; |
172 #endif | 187 #endif |
173 | |
174 sock_close(nbsock); | |
175 nbsock = -1; | |
176 | 188 |
177 needupdate = 0; | 189 needupdate = 0; |
178 inAtomic = 0; | 190 inAtomic = 0; |
179 nb_free(); | 191 nb_free(); |
180 | 192 |
630 netbeans_parse_messages(void) | 642 netbeans_parse_messages(void) |
631 { | 643 { |
632 char_u *p; | 644 char_u *p; |
633 queue_T *node; | 645 queue_T *node; |
634 | 646 |
635 if (!NETBEANS_OPEN) | |
636 return; | |
637 | |
638 while (head.next != NULL && head.next != &head) | 647 while (head.next != NULL && head.next != &head) |
639 { | 648 { |
640 node = head.next; | 649 node = head.next; |
641 | 650 |
642 /* Locate the first line in the first buffer. */ | 651 /* Locate the first line in the first buffer. */ |
717 GdkInputCondition unused2 UNUSED) | 726 GdkInputCondition unused2 UNUSED) |
718 { | 727 { |
719 netbeans_read(); | 728 netbeans_read(); |
720 } | 729 } |
721 #endif | 730 #endif |
731 | |
732 #define DETACH_MSG "DETACH\n" | |
722 | 733 |
723 void | 734 void |
724 netbeans_read() | 735 netbeans_read() |
725 { | 736 { |
726 static char_u *buf = NULL; | 737 static char_u *buf = NULL; |
778 readlen += len; | 789 readlen += len; |
779 if (len < MAXMSGSIZE) | 790 if (len < MAXMSGSIZE) |
780 break; /* did read everything that's available */ | 791 break; /* did read everything that's available */ |
781 } | 792 } |
782 | 793 |
794 /* Reading a socket disconnection (readlen == 0), or a socket error. */ | |
783 if (readlen <= 0) | 795 if (readlen <= 0) |
784 { | 796 { |
785 /* read error or didn't read anything */ | 797 /* Queue a "DETACH" netbeans message in the command queue in order to |
786 netbeans_close(); | 798 * terminate the netbeans session later. Do not end the session here |
787 nbdebug(("messageFromNetbeans: Error in read() from socket\n")); | 799 * directly as we may be running in the context of a call to |
800 * netbeans_parse_messages(): | |
801 * netbeans_parse_messages | |
802 * -> autocmd triggered while processing the netbeans cmd | |
803 * -> ui_breakcheck | |
804 * -> gui event loop or select loop | |
805 * -> netbeans_read() | |
806 */ | |
807 save((char_u *)DETACH_MSG, strlen(DETACH_MSG)); | |
808 nb_close_socket(); | |
809 | |
788 if (len < 0) | 810 if (len < 0) |
789 { | 811 { |
790 nbdebug(("read from Netbeans socket\n")); | 812 nbdebug(("read from Netbeans socket\n")); |
791 PERROR(_("read from Netbeans socket")); | 813 PERROR(_("read from Netbeans socket")); |
792 } | 814 } |
793 return; /* don't try to parse it */ | |
794 } | 815 } |
795 | 816 |
796 #if defined(NB_HAS_GUI) && defined(FEAT_GUI_GTK) | 817 #if defined(NB_HAS_GUI) && defined(FEAT_GUI_GTK) |
797 if (NB_HAS_GUI && gtk_main_level() > 0) | 818 if (NB_HAS_GUI && gtk_main_level() > 0) |
798 gtk_main_quit(); | 819 gtk_main_quit(); |
799 #endif | 820 #endif |
800 } | 821 } |
801 | 822 |
802 /* | 823 /* |
803 * Handle one NUL terminated command. | 824 * Handle one NUL terminated command. |
1161 nb_reply_nil(int cmdno) | 1182 nb_reply_nil(int cmdno) |
1162 { | 1183 { |
1163 char reply[32]; | 1184 char reply[32]; |
1164 | 1185 |
1165 nbdebug(("REP %d: <none>\n", cmdno)); | 1186 nbdebug(("REP %d: <none>\n", cmdno)); |
1187 | |
1188 /* Avoid printing an annoying error message. */ | |
1189 if (!NETBEANS_OPEN) | |
1190 return; | |
1166 | 1191 |
1167 sprintf(reply, "%d\n", cmdno); | 1192 sprintf(reply, "%d\n", cmdno); |
1168 nb_send(reply, "nb_reply_nil"); | 1193 nb_send(reply, "nb_reply_nil"); |
1169 } | 1194 } |
1170 | 1195 |
2751 ex_nbstart(eap) | 2776 ex_nbstart(eap) |
2752 exarg_T *eap; | 2777 exarg_T *eap; |
2753 { | 2778 { |
2754 #ifdef FEAT_GUI | 2779 #ifdef FEAT_GUI |
2755 # if !defined(FEAT_GUI_X11) && !defined(FEAT_GUI_GTK) \ | 2780 # if !defined(FEAT_GUI_X11) && !defined(FEAT_GUI_GTK) \ |
2756 && !defined(FEAT_GUI_W32) | 2781 && !defined(FEAT_GUI_W32) |
2757 if (gui.in_use) | 2782 if (gui.in_use) |
2758 { | 2783 { |
2759 EMSG(_("E838: netbeans is not supported with this GUI")); | 2784 EMSG(_("E838: netbeans is not supported with this GUI")); |
2760 return; | 2785 return; |
2761 } | 2786 } |
2762 # endif | 2787 # endif |
2763 #endif | 2788 #endif |
2764 netbeans_open((char *)eap->arg, FALSE); | 2789 netbeans_open((char *)eap->arg, FALSE); |
2765 } | 2790 } |