@@ -86,14 +86,8 @@ public PyMobileDevice3IPC() throws IOException {
8686 while (true ) {
8787 try {
8888 String line = reader .readLine ();
89- if (line == null ) {
90- for (CompletableFuture <?> future : futures .values ()) {
91- future .completeExceptionally (new PyMobileDevice3Error ("Python process died" ));
92- }
93-
94- close ();
95- return ;
96- }
89+ if (line == null )
90+ throw new IOException ("End of stream" );
9791 JSONObject jsonObject = new JSONObject (line );
9892 if (jsonObject .get ("state" ).equals ("failed" )) {
9993 String request = jsonObject .getString ("request" );
@@ -110,6 +104,7 @@ public PyMobileDevice3IPC() throws IOException {
110104
111105 handler .accept (jsonObject );
112106 } catch (IOException e ) {
107+ closePythonProcessDied ();
113108 break ;
114109 }
115110 }
@@ -118,6 +113,14 @@ public PyMobileDevice3IPC() throws IOException {
118113 readThread .start ();
119114 }
120115
116+ private void closePythonProcessDied ()
117+ {
118+ for (CompletableFuture <?> future : futures .values ())
119+ future .completeExceptionally (new PyMobileDevice3Error ("Python process died" ));
120+
121+ close ();
122+ }
123+
121124 private int readVersion () throws IOException {
122125 try {
123126 socket .setSoTimeout (2000 );
@@ -455,21 +458,25 @@ public boolean isAlive() {
455458
456459 @ Override
457460 public void close () {
458- try {
459- writeThread .interrupt ();
460- writeThread .join ();
461-
462- socket .close ();
463- commandResults .clear ();
464- writeQueue .clear ();
465-
466- readThread .interrupt ();
467- readThread .join ();
468-
469- futures .values ().forEach (completableFuture -> completableFuture .cancel (true ));
470- futures .clear ();
461+ if (destroyed )
462+ return ;
463+
464+ tryClose (writeThread ::interrupt );
465+ tryClose (writeThread ::join );
466+ tryClose (socket );
467+ tryClose (commandResults ::clear );
468+ tryClose (writeQueue ::clear );
469+ tryClose (readThread ::interrupt );
470+ tryClose (readThread ::join );
471+ tryClose (() -> futures .values ().forEach (completableFuture -> tryClose (() -> completableFuture .cancel (true ))));
472+ tryClose (futures ::clear );
473+
474+ destroyed = true ;
475+ }
471476
472- destroyed = true ;
473- } catch (IOException | InterruptedException ignored ) {}
477+ private void tryClose (AutoCloseable operation ) {
478+ try {
479+ operation .close ();
480+ } catch (Exception ignored ) {}
474481 }
475482}
0 commit comments