本人博客已经迁移到nasdaqgodzilla.github.io
文章目录
- 本人博客已经迁移到[nasdaqgodzilla.github.io](https://nasdaqgodzilla.github.io)
- 概述
- 原因
-
- wayland server对socket中的client数据的处理、方法调用的响应
- 解决方案
-
概述
- wayland server提供了由wayland协议文件定义的接口,client通过绑定这些接口后即可调用server的方法。
- 在使用google提供的wayland接口协议(
/wayland-protocols/unstable/remote-shell
)的时候,client完成对server资源的绑定后,调用remote_shell
的SetFrame
方法,调用完成后发现没有效果,并且在client发现与server的连接已经断开,通过调试手段发现server已经不再处理该client的方法调用以及surface_commit()
。
原因
wayland server对socket中的client数据的处理、方法调用的响应
- server在
src/wayland-server.c
中的方法 wl_client_connection_data()
对socket中client发过来的数据进行解析(反序列化)和处理。
- 在解析数据完成后,会调用客户端请求的方法。下面的
closure
就是即将调用的方法,通过invoke方法进行调用,原理是利用了ffi
库进行调用。
message = &object->interface->methods[opcode];since = wl_message_get_since(message);if (!(resource_flags & WL_MAP_ENTRY_LEGACY) &&resource->version > 0 && resource->version < since) {wl_resource_post_error(client->display_resource,WL_DISPLAY_ERROR_INVALID_METHOD,"invalid method %d (since %d < %d)"", object %s@%u",opcode, resource->version, since,object->interface->name,object->id);break;}closure = wl_connection_demarshal(client->connection, size,&client->objects, message);if (closure == NULL && errno == ENOMEM) {wl_resource_post_no_memory(resource);break;} else if (closure == NULL ||wl_closure_lookup_objects(closure, &client->objects) < 0) {wl_resource_post_error(client->display_resource,WL_DISPLAY_ERROR_INVALID_METHOD,"invalid arguments for %s@%u.%s",object->interface->name,object->id,message->name);wl_closure_destroy(closure);break;}log_closure(resource, closure, false);if ((resource_flags & WL_MAP_ENTRY_LEGACY) ||resource->dispatcher == NULL) {wl_closure_invoke(closure, WL_CLOSURE_INVOKE_SERVER,object, opcode, client);} else {wl_closure_dispatch(closure, resource->dispatcher,object, opcode);}wl_closure_destroy(closure);
- 调用失败的重点:在解析socket数据之前,会对client发过来的消息进行版本判断,如果检测到client的版本低于server要求的最低版本(即代码中的
since
),那么server就会通过wl_resource_post_error
来终止对该client的处理,并且会释放掉这个client相关的资源。故client会发现在调用一些方法后与server的连接会掉线,其原因就在于server认定版本不符合要求,主动断开了连接。
解决方案
临时解决-特别是快速调试和测试的时候
- 如果能修改server的代码,直接在上面这个文件(
wayland-server.c
)将起始版本(since
)修改为1,这样肯定不会被server认定版本不对而拒绝调用。强制调用会不会出问题就不知道了,反正在remote_shell``协议中强制调用它的
SetFrame```并不会出什么问题。
解决
- 将server和client的协议文件统一一下,并且重新生成接口和实现,统一版本。