# HG changeset patch # User Bram Moolenaar # Date 1289918942 -3600 # Node ID 73dd10c18ec4eb2cc0857417fb8cc20f63dd42e1 # Parent 75a89c7c204e0f478f480598cc3f2a8c45dee8b3 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) diff --git a/src/netbeans.c b/src/netbeans.c --- a/src/netbeans.c +++ b/src/netbeans.c @@ -135,14 +135,12 @@ static int dosetvisible = FALSE; static int needupdate = 0; static int inAtomic = 0; +/* + * Close the socket and remove the input handlers. + */ static void -netbeans_close(void) +nb_close_socket(void) { - if (!NETBEANS_OPEN) - return; - - netbeans_send_disconnect(); - #ifdef FEAT_GUI_X11 if (inputHandler != (XtInputId)NULL) { @@ -167,13 +165,27 @@ netbeans_close(void) # endif #endif + sock_close(nbsock); + nbsock = -1; +} + +/* + * Close the connection and cleanup. + * May be called when nb_close_socket() was called earlier. + */ + static void +netbeans_close(void) +{ + if (NETBEANS_OPEN) + { + netbeans_send_disconnect(); + nb_close_socket(); + } + #ifdef FEAT_BEVAL bevalServers &= ~BEVAL_NETBEANS; #endif - sock_close(nbsock); - nbsock = -1; - needupdate = 0; inAtomic = 0; nb_free(); @@ -632,9 +644,6 @@ netbeans_parse_messages(void) char_u *p; queue_T *node; - if (!NETBEANS_OPEN) - return; - while (head.next != NULL && head.next != &head) { node = head.next; @@ -720,6 +729,8 @@ messageFromNetbeans(gpointer clientData } #endif +#define DETACH_MSG "DETACH\n" + void netbeans_read() { @@ -780,22 +791,32 @@ netbeans_read() break; /* did read everything that's available */ } + /* Reading a socket disconnection (readlen == 0), or a socket error. */ if (readlen <= 0) { - /* read error or didn't read anything */ - netbeans_close(); - nbdebug(("messageFromNetbeans: Error in read() from socket\n")); + /* Queue a "DETACH" netbeans message in the command queue in order to + * terminate the netbeans session later. Do not end the session here + * directly as we may be running in the context of a call to + * netbeans_parse_messages(): + * netbeans_parse_messages + * -> autocmd triggered while processing the netbeans cmd + * -> ui_breakcheck + * -> gui event loop or select loop + * -> netbeans_read() + */ + save((char_u *)DETACH_MSG, strlen(DETACH_MSG)); + nb_close_socket(); + if (len < 0) { nbdebug(("read from Netbeans socket\n")); PERROR(_("read from Netbeans socket")); } - return; /* don't try to parse it */ } #if defined(NB_HAS_GUI) && defined(FEAT_GUI_GTK) if (NB_HAS_GUI && gtk_main_level() > 0) - gtk_main_quit(); + gtk_main_quit(); #endif } @@ -1164,6 +1185,10 @@ nb_reply_nil(int cmdno) nbdebug(("REP %d: \n", cmdno)); + /* Avoid printing an annoying error message. */ + if (!NETBEANS_OPEN) + return; + sprintf(reply, "%d\n", cmdno); nb_send(reply, "nb_reply_nil"); } @@ -2753,11 +2778,11 @@ ex_nbstart(eap) { #ifdef FEAT_GUI # if !defined(FEAT_GUI_X11) && !defined(FEAT_GUI_GTK) \ - && !defined(FEAT_GUI_W32) + && !defined(FEAT_GUI_W32) if (gui.in_use) { - EMSG(_("E838: netbeans is not supported with this GUI")); - return; + EMSG(_("E838: netbeans is not supported with this GUI")); + return; } # endif #endif diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -715,6 +715,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 60, +/**/ 59, /**/ 58,