Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows handling CTRL+C in different thread?

Here is a simple application that handled CTRL+C signal both on linux and windows:

#include <QtCore/QCoreApplication>
#include <QDebug>
#include <QThread>

void SigIntHandler()
{
    qDebug()<<"SigInt ThreadID: "<<QThread::currentThreadId();
    qApp->quit();
}

#ifdef __linux__
#include <signal.h>

    void unix_handler(int s)
    {
        //svakako je SIGINT, ali da ne javlja warning da se s ne koristi
        if (s==SIGINT)
            SigIntHandler();
    }

#else
#include <windows.h>

    BOOL WINAPI WinHandler(DWORD CEvent)
    {
        switch(CEvent)
        {
        case CTRL_C_EVENT:
            SigIntHandler();
            break;
        }
        return TRUE;
    }

#endif

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);


    //kod za hvatanje CTRL+C - unix i windows
    #ifdef __linux__
        signal(SIGINT, &unix_handler);
    #else
        SetConsoleCtrlHandler((PHANDLER_ROUTINE)WinHandler, TRUE);
    #endif

    qDebug()<<"Main ThreadID: "<<QThread::currentThreadId();
    return a.exec();
}

After compiling and running it on linux (Debian Squeeze), I get following output:

/Test-build-desktop$ ./Test 
Main ThreadID:  140105475446560 
^CSigInt ThreadID:  140105475446560 

/Test-build-desktop$ ./Test 
Main ThreadID:  140369579480864 
^CSigInt ThreadID:  140369579480864 

/Test-build-desktop$ ./Test 
Main ThreadID:  140571925509920 
^CSigInt ThreadID:  140571925509920 

And that's what I've expected (SigIntHandler method runs on main thread). But when I compile and execute same code on Windows 7, I get this:

d:\Test-build-desktop\debug>Test.exe
Main ThreadID:  0x5a8
SigInt ThreadID:  0x768

d:\Test-build-desktop\debug>Test.exe
Main ThreadID:  0x588
SigInt ThreadID:  0x1434

d:\Test-build-desktop\debug>Test.exe
Main ThreadID:  0x1170
SigInt ThreadID:  0xc38

As you can see, here SigIntHandler method is executed in different thread then main ... And that creates me many problems. So my question is - is it possible to force SigIntHandler to run in main thread on windows ? Am I maybe catching siging wrong ?

Thanks !!

like image 816
xx77aBs Avatar asked Sep 13 '11 15:09

xx77aBs


People also ask

Is CTRL c sigterm?

By default, when a console window has the keyboard focus, CTRL + C or CTRL + BREAK is treated as a signal (SIGINT or SIGBREAK) and not as keyboard input. By default, these signals are passed to all console processes that are attached to the console.

How do you send a Sigint to a Windows running process?

SIGINT can be send to program using windows-kill, by syntax windows-kill -SIGINT PID , where PID can be obtained by Microsoft's pslist. Regarding catching SIGINTs, if your program is in Python then you can implement SIGINT processing/catching like in this solution.

What is CTRL C signal?

While in a command line such as MS-DOS, Linux, and Unix, Ctrl + C is used to send a SIGINT signal, which cancels or terminates the currently-running program. For example, if a script or program is frozen or stuck in an infinite loop, pressing Ctrl + C cancels that command and returns you to the command line.


1 Answers

From MSDN topic HandlerRoutine:

A HandlerRoutine function is an application-defined function used with the SetConsoleCtrlHandler function. A console process uses this function to handle control signals received by the process. When the signal is received, the system creates a new thread in the process to execute the function.

So, the answer is: this is impossible.

like image 74
Alex F Avatar answered Sep 18 '22 00:09

Alex F