zoukankan      html  css  js  c++  java
  • 多进程DirectFB用X11显示的死锁问题

    多进程DirectFBX11显示的死锁问题


    转载时请注明出处和作者联系方式
    作者联系方式:李先静 <xianjimli at hotmail dot com>

    多进程的DirectFBX11SDL显示时,有一个固有的死锁问题,其原理如下:

    SLAVE进程调用dfb_layer_region_flip_update去刷新屏幕,这个函数最后会调用虚函数UpdateRegion。对于X11SDL显示的情况下,SLAVE只能通过MASTER才能刷新屏幕,SLAVE是调用fusion_call_executeMASTER刷新屏幕的。这下问题来了:调用fusion_call_execute之前SLAVE可能已经锁住了窗口栈和要更新的RegionMASTER收到调用请求后,又去锁定窗口栈和要更新的Region,结果是SLAVEMASTER执行刷新操作,而MASTER在等SLAVE锁定的锁。

    这个死锁问题已经存在好几年了,在最新的DirectFB-1.1.1中仍然存在。很难给这个问题找一个完美的解决方案,不过考虑到在X11/SDL上显示主要是为了开发调试方便,加上手机应用的特殊性(一般只有一个窗口上前)我们可以接受一个有缺陷但实用的解决方案,我做了下列尝试,效果还可以:

    修改函数dfb_layer_region_flip_update:

    调用UpdateRegion之前先解锁:
    #ifdef LINUX_I386

    int i = 0;
    int pid = getpid();
    int lock_pid = 0;
    int lock_count = 0;

    fusion_skirmish_lock_pid(
    &region->context->lock&lock_pid);
    if(pid == lock_pid)

    {
        fusion_skirmish_lock_count(
    &region->context->lock&lock_count);

        
    for(i = 0; i < lock_count; i++)

        
    {
            dfb_layer_context_unlock(region
    ->context);
        }


    }


    dfb_layer_region_unlock( region );

    #endif

    调用UpdateRegion之后再加锁:

     


    #ifdef LINUX_I386
    if(pid == lock_pid)
    {
        
    for(i = 0; i < lock_count; i++)
        
    {
            dfb_layer_context_lock(region
    ->context);
        }

    }

    dfb_layer_region_lock( region );
    #endif 

    fusion_skirmish_lock_pid是新加的函数(要修改fusion),用于获取加锁进程的PID,只有是当前进程加的锁才解锁。这样修改之后,一个原子变成两个原子了,违背了设计者初衷。但根据代码的上下文和手机应用的特殊性(只显示一个窗口)来看,这样修改造成问题的可能性很小。

    另外,SLAVE里面除了GUI线程更新窗口外,fusion线程可能会更新光标,为了避免SLAVE多线程同时刷新屏幕,再修改一下IDirectFBWindow_React,注释掉下面两行代码:


        dfb_windowstack_cursor_set_shape( data->window->stack,
        shape_data
    ->surface,
        data
    ->cursor.hot_x,
        data
    ->cursor.hot_y );
        dfb_windowstack_cursor_set_opacity( data
    ->window->stack, 0xff );

    这个修改的副作用是窗口光标的形状不会及时改变,对功能没有什么影响。

    ~~end~~

  • 相关阅读:
    String substring(int start,int end)截取当前字符串中指定范围内的字符串
    String字符串是不变对象,内容一旦创建不可改变,若改变一定会创建新对象
    StringBuilder修改字符串内容,增,删,改,插
    startsWith(),endsWith()判断当前字符串是否是以给定字符串开始或结尾的
    length()返回当前字符串的字符个数
    indexOf()字符位置
    charAt()检测回文
    手把手教你猜字小游戏
    release 和 drain
    c专家编程 ,c语言运行时环境
  • 原文地址:https://www.cnblogs.com/zhangyunlin/p/6167638.html
Copyright © 2011-2022 走看看