Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于一个死锁问题 #87

Closed
htk719809837 opened this issue Sep 7, 2022 · 16 comments
Closed

关于一个死锁问题 #87

htk719809837 opened this issue Sep 7, 2022 · 16 comments

Comments

@htk719809837
Copy link

前提:在创建对话框以后,对齐进行整个移动,MoveWindow()的操作(这里我们是输入框向上移动)
操作:然后通过CreateMainWindowIndirectParam()创建一个新的对话框(这里我们是基于对话框创建创建键盘),这个ui卡住,但是不崩溃
问题排查:
通过CreateMainWindowIndirectParam()创建基于对话框的键盘会默认
走到dialog.c中
hMainWin = CreateMainWindowEx (&CreateInfo,
werdr_name, we_attrs, window_name, layer_name);
如上的创建函数里面。
进一步跟到:window.c中
if (SendMessage (HWND_DESKTOP, MSG_ADDNEWMAINWIN, (WPARAM) pWin, 0) < 0)
goto err;
进一步跟到:desktop-comm.c中
case MSG_ADDNEWMAINWIN:
#ifdef _MGHAVE_MENU
if (sg_ptmi)
dskForceCloseMenu ();
#endif
return dskAddNewMainWindow(pWin);
再跟到:desktop.c中
dskMoveWindow
AllocZOrderNodeEx()函数:
到这个函数走不下去了,发现卡在lock_zi_for_change(zi)走不下去了,发现该值为负值溢出为正,导致进行一次unlock后没有归零,无法进行写操作。
然后分析前后因果关系发现是由MoveWindow()导致的,所以去检查MoveWindow();
跟到:desktop.c中的
dskMoveWindow()函数中:发现在 update_client_window_rgn (nodes [idx_znode].cli,
nodes [idx_znode].hwnd);
这句下面有一句
/* unlock zi for change ... */
unlock_zi_for_change (zi);
解锁函数,这里与minigui3不同样,minigui3将这句话放在了稍微前面一点的EmptyClipRgn (&sg_UpdateRgn);之后;

看到提交记录里面有对其进行一个修改,但是修改并不生效。

*******归结起来分析出来就是在desktop.c中的dskMoveWindow()函数中,有一句unlock_zi_for_change (zi);被移动了位置,导致进行一次unlock后没有归零,无法进行写操作,但是我尝试按照3.0的思路移动到前面,却不起任何作用,打算跟一步跟进的时候发现内部实现过于复杂了,所以想问一下是不是有解决方法

@VincentWei
Copy link
Owner

请问您的代码基线?是 rel-5-0 分支的最新版本还是 master 分支的最新版本?

@htk719809837
Copy link
Author

我的代码是今年7月13日在minigui官网下载的,因为网络问题并没有通过git拉取,但是按照rel-5-0 分支的2e8eba7dd0a0d3c15f9ed58e7a3b5282e47fa8ca和f76c9187a8f3edb9d64b97826506538a1c324b8b两个提交记录修改以后并没有解开这个死锁

@htk719809837
Copy link
Author

按照#83修改以后似乎并没有被修复

@VincentWei
Copy link
Owner

请贴一段用于重现该缺陷的代码,可编译为可执行程序的,以方便调试。谢谢!

@VincentWei
Copy link
Owner

并告知 MiniGUI 的运行模式。

@htk719809837
Copy link
Author

使用的是线程模式,我准备切换到rel-5-0分支去尝试是否解开死锁,但是好像编译方式不太一样,./autogen.sh,也会有报错,看到新增了cmakelist,是不是修改了编译方式呢

@VincentWei
Copy link
Owner

VincentWei commented Sep 14, 2022

MiniGUI 5.0 的构建仍然使用的是 autotools,跟 MiniGUI 3.0 没有本质区别,但某些配置选项发生了变化。

您可以参考如下仓库中的构建脚本:

https://github.com/VincentWei/build-minigui-5.0

@VincentWei
Copy link
Owner

确认了一下,死锁问题是在五月底解决的,是 5.0.9 版本发布之后,代码在 rel-5-0 分支上,尚未合并到 master 分支。

如果习惯使用软件包,可以切换到 rel-5-0 分支,在 PC 上进行配置,然后运行 make dist 命令打包成 5.0.10 的 tar.gz 包然后再放到你自己的项目中构建。

@htk719809837
Copy link
Author

用了最新版本 rel-5-0,死锁并没有解决,能麻烦问一下当时死锁的原因是什么吗,从提交历史只看到了unlock zi for change (zi);移动了位置,还有一处定义改变了,但是并没有解决这个问题,在3.0中不存在这个死锁,如果有时间我会提供一个demo,不过还是想了解一下死锁产生的原因,谢谢!

@VincentWei
Copy link
Owner

属于缺陷。要快速解决您遇到的问题,还是要给出可以重现缺陷的代码,这样才能帮我们快速定位问题、解决问题。

@htk719809837
Copy link
Author

#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <minigui/control.h>
#include <stdio.h>
#include <string.h>
static LRESULT pwdlogin_ime_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
printf("message in : %d \n", message);
switch (message)
{
case MSG_CREATE:
{
hWnd = CreateWindowEx(CTRL_BUTTON,
"333333333",
WS_CHILD | WS_VISIBLE ,
WS_EX_NONE,
103,
50, 100, 105, 40, hWnd, 0);
break;
}
case MSG_COMMAND:
{

    break;
    }

 }
 
 return DefaultMainWinProc(hWnd, message, wParam, lParam);

}
static LRESULT pwdlogin_window_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
printf("message in : %d \n", message);
switch (message)
{
case MSG_CREATE:
{
hWnd = CreateWindowEx(CTRL_BUTTON,
"222222",
WS_CHILD | WS_VISIBLE ,
WS_EX_NONE,
101,
50, 100, 105, 40, hWnd, 0);
break;
}
case MSG_COMMAND:
{
if(101 == wParam)
{
MoveWindow(hWnd,0,-100,200,200,TRUE);
DLGTEMPLATE stDlg;
memset(&stDlg, 0, sizeof(stDlg));
stDlg.dwStyle = WS_VISIBLE | WS_CAPTION | WS_BORDER;
stDlg.dwExStyle = WS_EX_NONE;
stDlg.x = 0;
stDlg.y = 0;
stDlg.w = 200;
stDlg.h = 200;
stDlg.caption = "1111";
CreateMainWindowIndirectParam(&stDlg, hWnd, pwdlogin_ime_proc, 0);

    	}
    break;
    }

 }
 
 return DefaultMainWinProc(hWnd, message, wParam, lParam);

}
static LRESULT HelloWinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

switch (message) {
    case MSG_CREATE:
        hWnd = CreateWindowEx(CTRL_BUTTON,
        "11111111111",
        WS_CHILD | WS_VISIBLE ,  
        WS_EX_TRANSPARENT,
        100,
        50, 50, 105, 40, hWnd, 0);
        break;
    case MSG_COMMAND:
    	if(100 == wParam)
    	{	
    
    	    DLGTEMPLATE stDlg;
                memset(&stDlg, 0, sizeof(stDlg));
	    stDlg.dwStyle = WS_VISIBLE | WS_CAPTION | WS_BORDER;
	    stDlg.dwExStyle = WS_EX_NONE;
	    stDlg.x = 0;
	    stDlg.y = 0;
	    stDlg.w = 200;
	    stDlg.h = 200;
	    stDlg.caption = "";
    	    CreateMainWindowIndirectParam(&stDlg, hWnd, pwdlogin_window_proc, 0);
    	}
    	 break;
    case MSG_CLOSE:
        DestroyMainWindow (hWnd);
        PostQuitMessage (hWnd);
        break;
}
return DefaultMainWinProc(hWnd, message, wParam, lParam);

}

int MiniGUIMain (int argc, const char* argv[])
{
MSG Msg;
HWND hMainWnd;
MAINWINCREATE CreateInfo;
#ifdef _MGRM_PROCESSES
JoinLayer(NAME_DEF_LAYER , "helloworld" , 0 , 0);
#endif

CreateInfo.dwStyle = WS_VISIBLE | WS_CAPTION;
CreateInfo.dwExStyle = WS_EX_NONE;
CreateInfo.spCaption = "Hello";
CreateInfo.hMenu = 0;
CreateInfo.hCursor = GetSystemCursor(0);
CreateInfo.hIcon = 0;
CreateInfo.MainWindowProc = HelloWinProc;
CreateInfo.lx = 0;
CreateInfo.ty = 0;
CreateInfo.rx = 480;
CreateInfo.by = 272;
CreateInfo.iBkColor = COLOR_lightwhite;
CreateInfo.dwAddData = 0;
CreateInfo.hHosting = HWND_DESKTOP;
hMainWnd = CreateMainWindow (&CreateInfo);
if (hMainWnd == HWND_INVALID)
    return -1;
ShowWindow(hMainWnd, SW_SHOWNORMAL);

while (GetMessage(&Msg, hMainWnd)) {
    TranslateMessage(&Msg);
    DispatchMessage(&Msg);
}
MainWindowThreadCleanup (hMainWnd);
return 0;

}
#ifdef _MGRM_THREADS
#include <minigui/dti.c>
#endif

由于网络问题无法上传文件,代码在上面,死锁的图片就不提供了,麻烦看一下啦,用的线程模式

@htk719809837
Copy link
Author

这个仿照出现死锁情况的业务代码逻辑写的一个demo

@VincentWei
Copy link
Owner

ok, thanks!

VincentWei added a commit that referenced this issue Sep 14, 2022
… holding the wrlock, skip rdlock if the wrlock owner is the current thread
@VincentWei
Copy link
Owner

请确认修复并反馈。修复在 rel-5-0 分支中。若无问题,将合并到 master 分支,并发布 5.0.10 版本。

谢谢!

@htk719809837
Copy link
Author

目前看来已经修复,我这边业务逻辑也没有出现死锁了,谢谢!期待5.0.10发布!

@VincentWei
Copy link
Owner

好的!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants