Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bd8c83db authored by Maksymilian Osowski's avatar Maksymilian Osowski
Browse files

Fixed the bug in forwarder that prevented ConnectionHandler threads from exiting.

There was a deadlock when ConnectionHandler exited the loop in SocketPipeThread, and would call the onFinishedCallback, which called the synchronized method in Forwarder that would
deadlock. Changing the Forwarder class solved the issue and made it more efficient.

Change-Id: I947450a19573f2e88274b1ebc7b77d4df6afffa7
parent fddedbf9
Loading
Loading
Loading
Loading
+16 −2
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ public class ConnectionHandler {
                }
            } catch (IOException e) {
                Log.w(LOG_TAG, this.toString(), e);
                finish();
                return;
            }

@@ -74,9 +75,18 @@ public class ConnectionHandler {
                }
            }

            finish();
        }

        private void finish() {
            synchronized (mThreadsRunning) {
                mThreadsRunning--;
                if (mThreadsRunning == 0) {
                    ConnectionHandler.this.stop();
                    mOnFinishedCallback.onFinished();
                }
            }
        }

        @Override
        public String toString() {
@@ -84,6 +94,8 @@ public class ConnectionHandler {
        }
    }

    private Integer mThreadsRunning;

    private Socket mFromSocket, mToSocket;
    private SocketPipeThread mFromToPipe, mToFromPipe;

@@ -101,6 +113,8 @@ public class ConnectionHandler {
    }

    public void start() {
        /** We have 2 threads running, one for each pipe, that we start here. */
        mThreadsRunning = 2;
        mFromToPipe.start();
        mToFromPipe.start();
    }
+46 −57
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@ public class Forwarder extends Thread {
    private int mPort;
    private String mRemoteMachineIpAddress;

    private Boolean mIsRunning = false;
    private ServerSocket mServerSocket;

    private Set<ConnectionHandler> mConnectionHandlers = new HashSet<ConnectionHandler>();
@@ -55,18 +54,12 @@ public class Forwarder extends Thread {
            return;
        }

        mIsRunning = true;
        super.start();
    }

    @Override
    public void run() {
        while (true) {
            synchronized (this) {
                if (!mIsRunning) {
                    return;
                }

            /** These sockets will be closed when Forwarder.stop() is called */
            Socket localSocket;
            Socket remoteSocket;
@@ -77,7 +70,7 @@ public class Forwarder extends Thread {
            } catch (IOException e) {
                /** This most likely means that mServerSocket is already closed */
                Log.w(LOG_TAG, "mPort=" + mPort, e);
                    return;
                break;
            }

            if (remoteSocket == null) {
@@ -104,22 +97,27 @@ public class Forwarder extends Thread {
                    new ConnectionHandler.OnFinishedCallback() {
                @Override
                public void onFinished() {
                        removeConncetionHandler(connectionHandler);
                    synchronized (this) {
                        if (mConnectionHandlers.remove(connectionHandler)) {
                            Log.d(LOG_TAG, "removeConnectionHandler(): removed");
                        } else {
                            assert false : "removeConnectionHandler(): not in the collection";
                        }
                    }
                }
            };
            connectionHandler.registerOnConnectionHandlerFinishedCallback(callback);

            synchronized (this) {
                mConnectionHandlers.add(connectionHandler);
                connectionHandler.start();
            }
            }
            connectionHandler.start();
        }

    private synchronized void removeConncetionHandler(ConnectionHandler connectionHandler) {
        if (mConnectionHandlers.remove(connectionHandler)) {
            Log.d(LOG_TAG, "removeConnectionHandler(): removed");
        } else {
            Log.d(LOG_TAG, "removeConnectionHandler(): not in the collection");
        synchronized (this) {
            for (ConnectionHandler connectionHandler : mConnectionHandlers) {
                connectionHandler.stop();
            }
        }
    }

@@ -129,14 +127,5 @@ public class Forwarder extends Thread {
        } catch (IOException e) {
            Log.e(LOG_TAG, "mPort=" + mPort, e);
        }

        synchronized (this) {
            mIsRunning = false;
        }

        for (ConnectionHandler connectionHandler : mConnectionHandlers) {
            connectionHandler.stop();
        }
        mConnectionHandlers.clear();
    }
}
 No newline at end of file