From c66925a6b8e7e956c307c8a6e6e108626ea19cb5 Mon Sep 17 00:00:00 2001 From: Rodrigo Mesquita Date: Tue, 7 Oct 2025 14:10:08 +0100 Subject: [PATCH] runInTerminal: Wait for proxy client before launching Fixes #95 --- hdb/Development/Debug/Adapter/Proxy.hs | 4 +++- hdb/Main.hs | 21 +++++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/hdb/Development/Debug/Adapter/Proxy.hs b/hdb/Development/Debug/Adapter/Proxy.hs index f212dba..de1114c 100644 --- a/hdb/Development/Debug/Adapter/Proxy.hs +++ b/hdb/Development/Debug/Adapter/Proxy.hs @@ -47,8 +47,9 @@ newtype ProxyLog = ProxyLog T.Text -- 2.1 Read stdin from the socket and push it to a Chan -- 2.1 Read from a stdout Chan and write to the socket serverSideHdbProxy :: Recorder (WithSeverity ProxyLog) + -> MVar () -> DebugAdaptor () -serverSideHdbProxy l = do +serverSideHdbProxy l client_conn_signal = do DAS { syncProxyIn = dbIn , syncProxyOut = dbOut , syncProxyErr = dbErr } <- getDebugSession @@ -65,6 +66,7 @@ serverSideHdbProxy l = do runTCPServerWithSocket sock $ \scket -> do logWith l Info $ ProxyLog $ T.pack $ "Connected to client on port " ++ show port ++ "...!" + putMVar client_conn_signal () -- signal ready (see #95) -- -- Read stdout from chan and write to socket _ <- forkIO $ ignoreIOException $ do diff --git a/hdb/Main.hs b/hdb/Main.hs index 77a8049..f4ab502 100644 --- a/hdb/Main.hs +++ b/hdb/Main.hs @@ -7,6 +7,7 @@ import Data.Maybe import Data.Aeson import Data.IORef import Text.Read +import Control.Concurrent import Control.Monad import Control.Monad.IO.Class import Control.Monad.Except @@ -58,8 +59,9 @@ main = do let runLogger = loggerFinal hdbOpts l init_var <- liftIO (newIORef False{-not supported by default-}) pid_var <- liftIO (newIORef Nothing) + ccon_var <- liftIO newEmptyMVar runDAPServerWithLogger (toCologAction dapLogger) config - (talk runLogger init_var pid_var) + (talk runLogger init_var pid_var ccon_var) (ack runLogger pid_var) HdbCLI{..} -> do l <- handleLogger stdout @@ -143,14 +145,22 @@ talk :: Recorder (WithSeverity MainLog) -- ^ Whether the client supports runInTerminal -> IORef (Maybe Int) -- ^ The PID of the runInTerminal proxy process + -> MVar () + -- ^ A var to block on waiting for the proxy client to connect, if a proxy + -- connection is expected. See #95. -> Command -> DebugAdaptor () -------------------------------------------------------------------------------- -talk l support_rit_var pid_var = \ case +talk l support_rit_var pid_var client_proxy_signal = \ case CommandInitialize -> do InitializeRequestArguments{supportsRunInTerminalRequest} <- getArguments - liftIO $ writeIORef support_rit_var (fromMaybe False supportsRunInTerminalRequest) + let runInTerminal = fromMaybe False supportsRunInTerminalRequest + liftIO $ writeIORef support_rit_var runInTerminal sendInitializeResponse + -- If runInTerminal is not supported by the client, signal readiness right away + when (not runInTerminal) $ + liftIO $ putMVar client_proxy_signal () + -------------------------------------------------------------------------------- CommandLaunch -> do launch_args <- getArguments @@ -168,7 +178,7 @@ talk l support_rit_var pid_var = \ case when supportsRunInTerminalRequest $ do -- Run proxy thread, server side, and -- send the 'runInTerminal' request - serverSideHdbProxy (cmapWithSev RunProxyServerLog l) + serverSideHdbProxy (cmapWithSev RunProxyServerLog l) client_proxy_signal logWith l Info $ LaunchLog $ T.pack "Debugger launched successfully." @@ -192,6 +202,9 @@ talk l support_rit_var pid_var = \ case CommandConfigurationDone -> do sendConfigurationDoneResponse -- now that it has been configured, start executing until it halts, then send an event + + -- wait for the proxy client to connect before starting the execution (#95) + () <- liftIO $ takeMVar client_proxy_signal startExecution >>= handleEvalResult False ---------------------------------------------------------------------------- CommandThreads -> commandThreads