(Rename sources for RPC servers)
[moonshot-ui.git] / src / moonshot-server-msrpc.vala
1 using Rpc;
2 using MoonshotRpcInterface;
3
4 /* This class must be a singleton, because we use a global RPC
5  * binding handle. I cannot picture a situation where more than
6  * one instance of the same interface would be needed so this
7  * shouldn't be a problem.
8  *
9  * Shutdown is automatically done by the RPC runtime when the
10  * process ends
11  */
12 public class MoonshotServer : Object {
13     private static MainWindow main_window;
14
15     private static MoonshotServer instance = null;
16
17     public static void start (Gtk.Window window)
18     {
19         main_window = (MainWindow) window;
20         Rpc.server_start (MoonshotRpcInterface.spec, "/org/janet/Moonshot", Rpc.Flags.PER_USER);
21     }
22
23     public static MoonshotServer get_instance ()
24     {
25         if (instance == null)
26             instance = new MoonshotServer ();
27         return instance;
28     }
29
30     [CCode (cname = "moonshot_get_identity")]
31     public static void moonshot_get_identity (Rpc.AsyncCall call,
32                                               string nai,
33                                               string password,
34                                               string service,
35                                               ref string nai_out,
36                                               ref string password_out,
37                                               ref string certificate_out)
38     {
39         bool result = false;
40
41         var request = new IdentityRequest (main_window,
42                                            nai,
43                                            password,
44                                            service);
45
46         // Pass execution to the main loop and block the RPC thread
47         request.mutex = new Mutex ();
48         request.cond = new Cond ();
49         request.set_callback (return_identity_cb);
50
51         request.mutex.lock ();
52         Idle.add (request.execute);
53
54         while (request.complete == false)
55             request.cond.wait (request.mutex);
56
57         nai_out = "";
58         password_out = "";
59         certificate_out = "";
60
61         var id_card = request.id_card;
62         bool has_service = false;
63
64         if (id_card == null) {
65             foreach (string id_card_service in id_card.services)
66             {
67                 if (id_card_service == service)
68                     has_service = true;
69             }
70
71             if (has_service)
72             {
73                 // The strings are freed by the RPC runtime
74                 nai_out = id_card.nai;
75                 password_out = id_card.password;
76                 certificate_out = "certificate";
77
78                 result = true;
79             }
80         }
81
82         // The outputs must be set before this function is called. For this
83         // reason they are 'ref' not 'out' parameters - Vala assigns to the
84         // 'out' parameters only at the end of the function, which is too
85         // late.
86         call.return (&result);
87
88         request.cond.signal ();
89         request.mutex.unlock ();
90     }
91
92     // Called from the main loop thread when an identity has
93     // been selected
94     static void return_identity_cb (IdentityRequest request) {
95         // Notify the RPC thread that the request is complete
96         request.mutex.lock ();
97         request.cond.signal ();
98
99         // Block the main loop until the RPC call has returned
100         // to avoid any races
101         request.cond.wait (request.mutex);
102         request.mutex.unlock ();
103     }
104 }