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 }