comparison gui/win32/interface.c @ 24992:5701e23ebcb4

Better handling of win32 GUI thread: 1. Use _beginthreadex to create the GUI thread to avoid possible memory leak when linked to MS CRT. 2. Terminate the GUI thread in an cleaner way using PostThreadMessage() rather than the unrecommended TerminateThread().
author zuxy
date Sun, 11 Nov 2007 08:14:57 +0000
parents 71efd1fc20c8
children 304fc0bbefe1
comparison
equal deleted inserted replaced
24991:72bc6377fb28 24992:5701e23ebcb4
57 int mplGotoTheNext = 1; 57 int mplGotoTheNext = 1;
58 static gui_t *mygui = NULL; 58 static gui_t *mygui = NULL;
59 static int update_subwindow(void); 59 static int update_subwindow(void);
60 static RECT old_rect; 60 static RECT old_rect;
61 static DWORD style; 61 static DWORD style;
62 static HANDLE hThread;
63 static unsigned threadId;
62 ao_functions_t *audio_out = NULL; 64 ao_functions_t *audio_out = NULL;
63 vo_functions_t *video_out = NULL; 65 vo_functions_t *video_out = NULL;
64 mixer_t *mixer = NULL; 66 mixer_t *mixer = NULL;
65 67
66 /* test for playlist files, no need to specify -playlist on the commandline. 68 /* test for playlist files, no need to specify -playlist on the commandline.
457 } 459 }
458 video_out->control(VOCTRL_FULLSCREEN, 0); 460 video_out->control(VOCTRL_FULLSCREEN, 0);
459 if(sub_window) ShowWindow(mygui->subwindow, SW_SHOW); 461 if(sub_window) ShowWindow(mygui->subwindow, SW_SHOW);
460 } 462 }
461 463
462 static DWORD WINAPI GuiThread(void) 464 static unsigned __stdcall GuiThread(void* param)
463 { 465 {
464 MSG msg; 466 MSG msg;
465 467
466 if(!skinName) skinName = strdup("Blue"); 468 if(!skinName) skinName = strdup("Blue");
467 if(!mygui) mygui = create_gui(get_path("skins"), skinName, guiSetEvent); 469 if(!mygui) mygui = create_gui(get_path("skins"), skinName, guiSetEvent);
471 { 473 {
472 gtkAutoSyncOn = 1; 474 gtkAutoSyncOn = 1;
473 gtkAutoSync = autosync; 475 gtkAutoSync = autosync;
474 } 476 }
475 477
476 while(mygui) 478 while(GetMessage(&msg, NULL, 0, 0))
477 { 479 {
478 GetMessage(&msg, NULL, 0, 0);
479 TranslateMessage(&msg); 480 TranslateMessage(&msg);
480 DispatchMessage(&msg); 481 DispatchMessage(&msg);
481 } 482 }
482 fprintf(stderr, "[GUI] GUI thread terminated.\n"); 483 fprintf(stderr, "[GUI] GUI thread terminated.\n");
483 fflush(stderr); 484 fflush(stderr);
484 return 0; 485 return 0;
485 } 486 }
486 487
487 void guiInit(void) 488 void guiInit(void)
488 { 489 {
489 DWORD threadId;
490 memset(&guiIntfStruct, 0, sizeof(guiIntfStruct)); 490 memset(&guiIntfStruct, 0, sizeof(guiIntfStruct));
491 /* Create The gui thread */ 491 /* Create The gui thread */
492 if (!mygui) 492 if (!mygui)
493 { 493 {
494 CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) GuiThread, NULL, 0, &threadId); 494 hThread = _beginthreadex(NULL, 0, GuiThread, NULL, 0, &threadId);
495 mp_msg(MSGT_GPLAYER, MSGL_V, "[GUI] Creating GUI Thread 0x%04x\n", threadId); 495 mp_msg(MSGT_GPLAYER, MSGL_V, "[GUI] Creating GUI Thread 0x%04x\n", threadId);
496 } 496 }
497 497
498 /* Wait until the gui is created */ 498 /* Wait until the gui is created */
499 while(!mygui) Sleep(100); 499 while(!mygui) Sleep(100);
504 { 504 {
505 if(mygui) 505 if(mygui)
506 { 506 {
507 fprintf(stderr, "[GUI] Closed by main mplayer window\n"); 507 fprintf(stderr, "[GUI] Closed by main mplayer window\n");
508 fflush(stderr); 508 fflush(stderr);
509 PostThreadMessage(threadId, WM_QUIT, 0, 0);
510 WaitForSingleObject(hThread, INFINITE);
511 CloseHandle(hThread);
509 mygui->uninit(mygui); 512 mygui->uninit(mygui);
510 free(mygui); 513 free(mygui);
511 TerminateThread(GuiThread, 0);
512 mygui = NULL; 514 mygui = NULL;
513 } 515 }
514 /* Remove tray icon */ 516 /* Remove tray icon */
515 Shell_NotifyIcon(NIM_DELETE, &nid); 517 Shell_NotifyIcon(NIM_DELETE, &nid);
516 cfg_write(); 518 cfg_write();