Skip to content

Commit 611dddb

Browse files
committed
Implemented #8931: Avoid hangs when process with embedded connection goes into stopped state.
1 parent 0acd6e0 commit 611dddb

4 files changed

Lines changed: 67 additions & 1 deletion

File tree

src/common/os/os_utils.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,24 @@ namespace os_utils
386386
#endif
387387
};
388388

389+
class StopHandler
390+
{
391+
public:
392+
#ifdef WIN_NT
393+
explicit StopHandler(bool*)
394+
{ }
395+
#else
396+
explicit StopHandler(bool* stop);
397+
explicit StopHandler(Firebird::MemoryPool&);
398+
~StopHandler();
399+
400+
private:
401+
static bool* stopPtr;
402+
403+
static void handler(void*);
404+
#endif
405+
};
406+
389407
} // namespace os_utils
390408

391409
#endif // INCLUDE_OS_FILE_UTILS_H

src/common/os/posix/os_utils.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,4 +451,31 @@ void CtrlCHandler::handler(void*)
451451
terminated = true;
452452
}
453453

454+
/// class StopHandler
455+
456+
bool* StopHandler::stopPtr = nullptr;
457+
458+
StopHandler::StopHandler(bool* stop)
459+
{
460+
fb_assert(!stopPtr);
461+
stopPtr = stop;
462+
ISC_signal(SIGTSTP, handler, 0);
463+
}
464+
465+
StopHandler::StopHandler(MemoryPool&)
466+
{
467+
ISC_signal(SIGTSTP, handler, 0);
468+
}
469+
470+
StopHandler::~StopHandler()
471+
{
472+
ISC_signal_cancel(SIGTSTP, handler, 0);
473+
}
474+
475+
void StopHandler::handler(void*)
476+
{
477+
if (stopPtr)
478+
*stopPtr = true;
479+
}
480+
454481
} // namespace os_utils

src/isql/isql.epp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,8 @@ static inline int fb_isdigit(const char c)
301301
typedef Array<char> CharBuffer;
302302
GlobalPtr<CharBuffer> charBuffer;
303303

304+
static bool sigTstp = false;
305+
304306
#ifdef WIN_NT
305307

306308
GlobalPtr<Array<WCHAR>> wideBuffer;
@@ -789,6 +791,8 @@ int ISQL_main(int argc, char* argv[])
789791
*
790792
**************************************/
791793

794+
os_utils::StopHandler stopHandler(&sigTstp);
795+
792796
#if defined(HAVE_EDITLINE_H) && defined(HAVE_LOCALE_H)
793797
setlocale(LC_CTYPE, "");
794798
#endif
@@ -1023,7 +1027,22 @@ static void readNextInputLine(const char* prompt)
10231027
// CVC: On 2005-04-02, use an empty prompt when not working in
10241028
// interactive mode to behave like @@@ below at request by Pavel.
10251029
const char* new_prompt = Interactive ? prompt : "";
1026-
lastInputLine = readline(new_prompt);
1030+
for(;;)
1031+
{
1032+
lastInputLine = readline(new_prompt);
1033+
1034+
// In a case of ignored SIGTSTP (ctrl-Z typically) readline return NULL -
1035+
// same as for EOF case, causing normal termination. Let's avoid it.
1036+
if (!lastInputLine)
1037+
{
1038+
if (!sigTstp)
1039+
break;
1040+
sigTstp = false;
1041+
new_prompt = "";
1042+
}
1043+
else
1044+
break;
1045+
}
10271046

10281047
if (lastInputLine != NULL && strlen(lastInputLine) != 0) {
10291048
add_history(lastInputLine);

src/yvalve/why.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include "../common/IntlParametersBlock.h"
4949
#include "../common/os/isc_i_proto.h"
5050
#include "../common/os/path_utils.h"
51+
#include "../common/os/os_utils.h"
5152
#include "../common/classes/alloc.h"
5253
#include "../common/classes/array.h"
5354
#include "../common/classes/stack.h"
@@ -863,6 +864,7 @@ class ShutdownInit
863864
void signalInit()
864865
{
865866
#ifdef UNIX
867+
static GlobalPtr<os_utils::StopHandler> stopHandler;
866868
static GlobalPtr<CtrlCHandler> ctrlCHandler;
867869
#else
868870
static GlobalPtr<ShutdownInit> shutdownInit;

0 commit comments

Comments
 (0)