private static void HandleCancelQuery(WvDbus conn, WvDbusMsg msg) { log.print(WvLog.L.Debug4, "Received CancelQuery request\n"); //FIXME: Should I be in yet another thread? Action perform = null; if (msg.signature != "u" && msg.signature != "s") { //accept 's' signatures for Perl DBus, which is stupid and can't //send me 'u' parameters, even though the api accepts them. log.print(WvLog.L.Debug4, "CancelQuery: bad signature {0}\n", msg.signature); perform = () => { conn.send(msg.err_reply( "org.freedesktop.DBus.Error.UnknownMethod", "No overload of {0} has signature '{1}'", "CancelQuery", msg.signature)); }; } else { var it = msg.iter(); uint tokill; if (msg.signature == "s") { log.print(WvLog.L.Debug4, "CancelQuery: converting arg from string\n"); string temps = it.pop(); tokill = Convert.ToUInt32(temps); } else tokill = it.pop(); log.print(WvLog.L.Debug4, "CancelQuery: try killing msg id {0}\n", tokill); lock (action_mutex) { if (curaction != null && curaction.conn == conn && curaction.src.serial == tokill) { log.print(WvLog.L.Debug4, "CancelQuery: killing current action!\n"); WvSqlRows_IDataReader.Cancel(); curaction = null; } else { log.print(WvLog.L.Debug4, "CancelQuery: traversing action queue...\n"); //Traverse the action queue, killing stuff foreach (VxActionTriple t in action_queue) if (t.conn == conn && t.src.serial == tokill) { log.print(WvLog.L.Debug4, "CancelQuery: found culprit, killing.\n"); //action_queue.Remove(t); //FIXME: What message should we really put here? t.action = () => { conn.send(t.src.err_reply("vx.db.sqlerror", "This message got canceled")); }; break; } } } //Pointless return to make Perl happy. perform = () => { WvDbusWriter writer = new WvDbusWriter(); writer.Write("Cancel"); conn.send(msg.reply("s").write(writer)); }; log.print(WvLog.L.Debug4, "CancelQuery: complete\n"); } //FIXME: It's not clear whether for just add operations, in conjuction //with RemoveAt(0) going on in the otherthread, we need a mutex. action_queue.Add(new VxActionTriple(conn, msg, perform)); }
static int _Go(string cfgfile, string bus, string[] listeners) { StartDBusServerThread(listeners.ToArray()); if (cfgfile.e() && File.Exists("versaplexd.ini")) cfgfile = "versaplexd.ini"; if (cfgfile.e()) cfgfile = "/etc/versaplexd.ini"; log.print("Config file is '{0}'\n", cfgfile); VxSqlPool.SetIniFile(cfgfile); wv.assert(bus.ne()); log.print("Connecting to '{0}'\n", bus); conn = new WvDbus(bus); RequestNameReply rnr = conn.RequestName("vx.versaplexd", NameFlag.DoNotQueue); switch (rnr) { case RequestNameReply.PrimaryOwner: log.print("Name registered, ready\n"); break; default: log.print("Register name result: \n" + rnr.ToString()); return 2; } conn.stream.onclose += () => { log.print( "***********************************************************\n"+ "************ D-bus connection closed by server ************\n"+ "***********************************************************\n"); want_to_die = true; }; conn.handlers.Insert(0, (m) => WvDbusMsgReady(conn, m)); while (!want_to_die) { log.print(WvLog.L.Debug2, "Event loop.\n"); // We can't wait infinitely here, because someone in another // thread might set want_to_die. // (FIXME: in that case it's lame that we might ignore it for // a timeout. We should have a loopback stream of some sort // instead...) WvStream.runonce(1000); while (action_queue.Count > 0) { log.print(WvLog.L.Debug2, "Action queue.\n"); lock (action_mutex) { curaction = action_queue.First(); action_queue.RemoveAt(0); } curaction.action(); lock (action_mutex) { curaction = null; } log.print(WvLog.L.Debug2, "Action queue element done.\n"); } } log.print("Done!\n"); return 0; }