http://bugzilla.moblin.org/show_bug.cgi?id=6376
--- Comment #3 from pohly <patrick.ohly(a)intel.com> 2009-12-10 01:33:56 PST ---
(In reply to comment #2)
Here I give some my thinkings about this issue, just pseudocode
/** This function is called by session or others who want to ask information
from dbus clients */
bool DBusServer::handleInfoRequest(Session *session,const string &type,
std::map<string, string> ¶meters, std::map<string, string>
&response) {
emit signal InfoRequest("request") with a unique id(id)
m_id = id
m_reqStatus = "request"
g_main_loop_run(loop) /// add timeout mechanism
This should work. Getting out of g_main_loop_run() is always a bit tricky. For
example, Session::Abort() might have been called.
if(id == m_id && m_reqStatus == "response") {
response = m_response;
clear m_id, m_response
send signal InfoRequest("done")
return true;
}
// timeout or response status is not expected, return false
return false;
}
The caller might have to know whether a timeout occurred (=> use default reply)
or whether some other event occurred (=> handle that event).
There's one problem here: what if such a different event (Session::Abort(), new
data to process from a connection) causes DBusServer::handleInfoRequest() to
return? There's no way how the caller can resume waiting for a response or tell
DBusServer that the response is no longer needed. Additional API calls would be
needed for that.
Perhaps it would be simpler to not make DBusServer::handleInfoRequest()
blocking in the first place and design the API so that an info request is
started, checked and cancelled without blocking?
Also, only one info request can be pending at any time. This is probably a
valid simplification, but could be avoided by introducing a handle for it which
is passed around via smart pointers. Destructing the handle would automatically
cancel the request, which is in line with treating a pending info request as an
active resource.
// function for DBusServer DBus method 'InfoResponse'
DBusServer::infoResponse(string id, string state, std::map<string, string>
&response)
{
if (id != m_id) {
return; /// or throw an error?
"return" without error is fine. A client might reply to a request which is no
longer active at the time when the reply arrives.
} else if(state == "working") {
if m_reqStatus == "request"
send signal InfoRequest("waiting") /// what is the handler for the
replied client?
It's D-Bus ID, basically a plain string. You can get that by adding a Caller_t
parameter to D-Bus methods, as in connect().
else
ignore
} else if (state == "response") {
m_response = response /// possible no 'working' state sent by clients
g_main_loop_quit(loop)
}
}
Is the logic reasonable?
With the caveats mentioned above, yes.
questions:
1) If the active session request an info, do we need put it in the queue and
let the next waiting session run? Currently I assume not.
Correct, we don't need that.
2) what is the 'handler' for
InfoRequest("waiting")? we don't have any
information about which client sends the InfoResponse. Maybe we need add some
interfaces in dbus to fetch the dbus client identifier.
See above.
--
Configure bugmail:
http://bugzilla.moblin.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are watching someone on the CC list of the bug.