diff --git a/configure b/configure index 89b56680c5..cc23991fb7 100755 --- a/configure +++ b/configure @@ -1787,6 +1787,7 @@ SYSTEM_FUNCS=" pthread_cancel sched_getaffinity SetConsoleTextAttribute + SetConsoleCtrlHandler setmode setrlimit Sleep @@ -4990,6 +4991,7 @@ check_func_headers windows.h GetSystemTimeAsFileTime check_func_headers windows.h MapViewOfFile check_func_headers windows.h PeekNamedPipe check_func_headers windows.h SetConsoleTextAttribute +check_func_headers windows.h SetConsoleCtrlHandler check_func_headers windows.h Sleep check_func_headers windows.h VirtualAlloc check_struct windows.h "CONDITION_VARIABLE" Ptr diff --git a/ffmpeg.c b/ffmpeg.c index 37f096c1b1..e592629d0e 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -79,6 +79,10 @@ #include #include #endif +#if HAVE_SETCONSOLECTRLHANDLER +#include +#endif + #if HAVE_SYS_SELECT_H #include @@ -313,6 +317,7 @@ void term_exit(void) static volatile int received_sigterm = 0; static volatile int received_nb_signals = 0; static volatile int transcode_init_done = 0; +static volatile int ffmpeg_exited = 0; static int main_return_code = 0; static void @@ -329,6 +334,38 @@ sigterm_handler(int sig) } } +#if HAVE_SETCONSOLECTRLHANDLER +static BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) +{ + av_log(NULL, AV_LOG_DEBUG, "\nReceived windows signal %ld\n", fdwCtrlType); + + switch (fdwCtrlType) + { + case CTRL_C_EVENT: + case CTRL_BREAK_EVENT: + sigterm_handler(SIGINT); + return TRUE; + + case CTRL_CLOSE_EVENT: + case CTRL_LOGOFF_EVENT: + case CTRL_SHUTDOWN_EVENT: + sigterm_handler(SIGTERM); + /* Basically, with these 3 events, when we return from this method the + process is hard terminated, so stall as long as we need to + to try and let the main thread(s) clean up and gracefully terminate + (we have at most 5 seconds, but should be done far before that). */ + while (!ffmpeg_exited) { + Sleep(0); + } + return TRUE; + + default: + av_log(NULL, AV_LOG_ERROR, "Received unknown windows signal %ld\n", fdwCtrlType); + return FALSE; + } +} +#endif + void term_init(void) { #if HAVE_TERMIOS_H @@ -362,6 +399,9 @@ void term_init(void) #ifdef SIGXCPU signal(SIGXCPU, sigterm_handler); #endif +#if HAVE_SETCONSOLECTRLHANDLER + SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE); +#endif } /* read a key without blocking */ @@ -537,6 +577,7 @@ static void ffmpeg_cleanup(int ret) av_log(NULL, AV_LOG_INFO, "Conversion failed!\n"); } term_exit(); + ffmpeg_exited = 1; } void remove_avoptions(AVDictionary **a, AVDictionary *b)