All-zeroes mode is interpreted by compctl as a signal to stop looping.
Just remove this terminating mode in vesafb and compositor will hang
after the last mode had printed by compctl. I suppose it happens after
vs_enumerate_modes() fail to get out-of-range list element in modes
list and will return non-EOK status.
Aha, I see the problem now. It has nothing to do with connection hangup.
The root cause of the lockup is the desynchronization of the
communication protocol. As the client in visualizer_enumerate_modes()
(uspace/lib/c/generic/io/visualizer.c) always sends two methods in the
exchange (VISUALIZER_ENUMERATE_MODES and IPC_M_DATA_READ), the server in
vs_enumerate_modes() (uspace/lib/graph/graph.c) also has to receive both
methods in all cases and reply to them accordingly.
See the first patch attached that fixes the behaviour. Frankly, the same
incorrect anti-pattern is used all over graph.c, probably because the
code was written blindly some 3 years ago and it was never actually
tested and used so far.
I did so at first by then decided to save instructions. Can we threat
loop as a single logical session?
There is really no point in saving a few CPU cycles in mode listing.
This is hardly a performance-critical piece of code.
You should not treat the lopp as a single logical call, because it is
not one (from the IPC point of view). Each exchange (logical call) with
the server contains just a single message.
You won't achieve anything by enlarging the exchange, it won't even
guarantee a better consistency of the result, because the exchanges are
serialized on the client side, not on the server side.
Please use the correct client-side pattern as indicated in the second
patch attached.
M.D.
=== modified file 'uspace/lib/graph/graph.c'
--- uspace/lib/graph/graph.c 2013-09-10 16:32:35 +0000
+++ uspace/lib/graph/graph.c 2014-07-07 23:07:31 +0000
@@ -287,30 +287,34 @@
static void vs_enumerate_modes(visualizer_t *vs, ipc_callid_t iid, ipc_call_t *icall)
{
+ ipc_callid_t callid;
+ size_t len;
+
+ if (!async_data_read_receive(&callid, &len)) {
+ async_answer_0(callid, EREFUSED);
+ async_answer_0(iid, EREFUSED);
+ return;
+ }
+
fibril_mutex_lock(&vs->mode_mtx);
link_t *link = list_nth(&vs->modes, IPC_GET_ARG1(*icall));
-
+
if (link != NULL) {
vslmode_list_element_t *mode_elem =
list_get_instance(link, vslmode_list_element_t, link);
vslmode_t mode = mode_elem->mode;
fibril_mutex_unlock(&vs->mode_mtx);
-
- ipc_callid_t callid;
- size_t len;
-
- if (!async_data_read_receive(&callid, &len)) {
- async_answer_0(iid, EINVAL);
- return;
- }
- int rc = async_data_read_finalize(callid, &mode, len);
+
+ int rc = async_data_read_finalize(callid, &mode, len);
if (rc != EOK) {
async_answer_0(iid, ENOMEM);
return;
}
-
+
async_answer_0(iid, EOK);
} else {
+ fibril_mutex_unlock(&vs->mode_mtx);
+ async_answer_0(callid, ENOENT);
async_answer_0(iid, ENOENT);
}
}
=== modified file 'uspace/app/compctl/compctl.c'
--- uspace/app/compctl/compctl.c 2014-07-06 03:31:42 +0000
+++ uspace/app/compctl/compctl.c 2014-07-07 22:34:14 +0000
@@ -107,25 +107,21 @@
return pos;
}
int n;
- async_exch_t *exch = async_exchange_begin(ctl_sess);
for (n = 0; ; n++) {
+ async_exch_t *exch = async_exchange_begin(ctl_sess);
sysarg_t index, width, height, visual; // TODO freq
int rc = async_req_3_4(exch, COMPOSITOR_SELECT_VIEWPORT,
vp_id, VISUALIZER_ENUMERATE_MODES, n,
&index, &width, &height, &visual);
+ async_exchange_end(exch);
+
if (rc == EOK) {
- if (!index && !width && !height) {
- async_exchange_end(exch);
- goto done;
- }
printf("mode %#x: %zux%zu\n", (unsigned)index, width, height);
// TODO visual->bpp
} else if (rc == EINVAL) {
printf(NAME": %zu -- wrong viewport id\n", vp_id);
- async_exchange_end(exch);
return rc;
} else {
- async_exchange_end(exch);
return rc;
}
}
_______________________________________________
HelenOS-devel mailing list
[email protected]
http://lists.modry.cz/listinfo/helenos-devel