1 | /* |
---|
2 | * linc.c: This file is part of the linc library. |
---|
3 | * |
---|
4 | * Authors: |
---|
5 | * Elliot Lee (sopwith@redhat.com) |
---|
6 | * Michael Meeks (michael@ximian.com) |
---|
7 | * Mark McLouglin (mark@skynet.ie) & others |
---|
8 | * |
---|
9 | * Copyright 2001, Red Hat, Inc., Ximian, Inc., |
---|
10 | * Sun Microsystems, Inc. |
---|
11 | */ |
---|
12 | #include <signal.h> |
---|
13 | #include "linc-debug.h" |
---|
14 | #include "linc-private.h" |
---|
15 | |
---|
16 | static gboolean linc_threaded = FALSE; |
---|
17 | static gboolean linc_mutex_new_called = FALSE; |
---|
18 | GMainLoop *linc_loop = NULL; |
---|
19 | GMainContext *linc_context = NULL; |
---|
20 | static GMutex *linc_lifecycle_mutex = NULL; |
---|
21 | |
---|
22 | #ifdef LINC_SSL_SUPPORT |
---|
23 | SSL_METHOD *linc_ssl_method; |
---|
24 | SSL_CTX *linc_ssl_ctx; |
---|
25 | #endif |
---|
26 | |
---|
27 | /** |
---|
28 | * linc_set_threaded: |
---|
29 | * @threaded: whether to do locking |
---|
30 | * |
---|
31 | * This routine turns threading on or off for the whole |
---|
32 | * ORB, it should be called (TRUE) if threading is desired |
---|
33 | * before any of the ORB initialization occurs. |
---|
34 | **/ |
---|
35 | void |
---|
36 | linc_set_threaded (gboolean threaded) |
---|
37 | { |
---|
38 | if (linc_mutex_new_called) |
---|
39 | g_error ("You need to set this before using the ORB"); |
---|
40 | linc_threaded = threaded; |
---|
41 | } |
---|
42 | |
---|
43 | /** |
---|
44 | * linc_init: |
---|
45 | * @init_threads: if we want threading enabled. |
---|
46 | * |
---|
47 | * Initialize linc. |
---|
48 | **/ |
---|
49 | void |
---|
50 | linc_init (gboolean init_threads) |
---|
51 | { |
---|
52 | if ((init_threads || linc_threaded) && |
---|
53 | !g_thread_supported ()) |
---|
54 | g_thread_init (NULL); |
---|
55 | |
---|
56 | if (!linc_threaded && init_threads) |
---|
57 | linc_threaded = TRUE; |
---|
58 | |
---|
59 | g_type_init (); |
---|
60 | |
---|
61 | /* |
---|
62 | * Linc's raison d'etre is for ORBit2 and Bonobo |
---|
63 | * |
---|
64 | * In Bonobo, components and containers must not crash if the |
---|
65 | * remote end crashes. If a remote server crashes and then we |
---|
66 | * try to make a CORBA call on it, we may get a SIGPIPE. So, |
---|
67 | * for lack of a better solution, we ignore SIGPIPE here. This |
---|
68 | * is open for reconsideration in the future. |
---|
69 | * |
---|
70 | * When SIGPIPE is ignored, write() calls which would |
---|
71 | * ordinarily trigger a signal will instead return -1 and set |
---|
72 | * errno to EPIPE. So linc will be able to catch these |
---|
73 | * errors instead of letting them kill the component. |
---|
74 | * |
---|
75 | * Possibilities are the MSG_PEEK trick, where you test if the |
---|
76 | * connection is dead right before doing the writev(). That |
---|
77 | * approach has two problems: |
---|
78 | * |
---|
79 | * 1. There is the possibility of a race condition, where |
---|
80 | * the remote end calls right after the test, and right |
---|
81 | * before the writev(). |
---|
82 | * |
---|
83 | * 2. An extra system call per write might be regarded by |
---|
84 | * some as a performance hit. |
---|
85 | * |
---|
86 | * Another possibility is to surround the call to writev() in |
---|
87 | * linc_connection_writev (linc-connection.c) with something like |
---|
88 | * this: |
---|
89 | * |
---|
90 | * linc_ignore_sigpipe = 1; |
---|
91 | * |
---|
92 | * result = writev ( ... ); |
---|
93 | * |
---|
94 | * linc_ignore_sigpipe = 0; |
---|
95 | * |
---|
96 | * The SIGPIPE signal handler will check the global |
---|
97 | * linc_ignore_sigpipe variable and ignore the signal if it |
---|
98 | * is 1. If it is 0, it can proxy to the user's original |
---|
99 | * signal handler. This is a real possibility. |
---|
100 | */ |
---|
101 | signal (SIGPIPE, SIG_IGN); |
---|
102 | |
---|
103 | linc_context = g_main_context_new (); |
---|
104 | linc_loop = g_main_loop_new (linc_context, TRUE); |
---|
105 | |
---|
106 | #ifdef LINC_SSL_SUPPORT |
---|
107 | SSLeay_add_ssl_algorithms (); |
---|
108 | linc_ssl_method = SSLv23_method (); |
---|
109 | linc_ssl_ctx = SSL_CTX_new (linc_ssl_method); |
---|
110 | #endif |
---|
111 | |
---|
112 | linc_lifecycle_mutex = linc_mutex_new (); |
---|
113 | } |
---|
114 | |
---|
115 | /** |
---|
116 | * linc_main_iteration: |
---|
117 | * @block_for_reply: whether we should wait for a reply |
---|
118 | * |
---|
119 | * This routine iterates the linc mainloop, which has |
---|
120 | * only the linc sources registered against it. |
---|
121 | **/ |
---|
122 | void |
---|
123 | linc_main_iteration (gboolean block_for_reply) |
---|
124 | { |
---|
125 | g_main_context_iteration ( |
---|
126 | linc_context, block_for_reply); |
---|
127 | } |
---|
128 | |
---|
129 | /** |
---|
130 | * linc_main_pending: |
---|
131 | * |
---|
132 | * determines if the linc mainloop has any pending work to process. |
---|
133 | * |
---|
134 | * Return value: TRUE if the linc mainloop has any pending work to process. |
---|
135 | **/ |
---|
136 | gboolean |
---|
137 | linc_main_pending (void) |
---|
138 | { |
---|
139 | return g_main_context_pending (linc_context); |
---|
140 | } |
---|
141 | |
---|
142 | /** |
---|
143 | * linc_main_loop_run: |
---|
144 | * |
---|
145 | * Runs the linc mainloop; blocking until the loop is exited. |
---|
146 | **/ |
---|
147 | void |
---|
148 | linc_main_loop_run (void) |
---|
149 | { |
---|
150 | g_main_loop_run (linc_loop); |
---|
151 | } |
---|
152 | |
---|
153 | /** |
---|
154 | * linc_mutex_new: |
---|
155 | * |
---|
156 | * Creates a mutes, iff threads are supported, initialized and |
---|
157 | * linc_set_threaded has been called. |
---|
158 | * |
---|
159 | * Return value: a new GMutex, or NULL if one is not required. |
---|
160 | **/ |
---|
161 | GMutex * |
---|
162 | linc_mutex_new (void) |
---|
163 | { |
---|
164 | linc_mutex_new_called = TRUE; |
---|
165 | |
---|
166 | #ifdef G_THREADS_ENABLED |
---|
167 | if (linc_threaded && g_thread_supported ()) |
---|
168 | return g_mutex_new (); |
---|
169 | #endif |
---|
170 | |
---|
171 | return NULL; |
---|
172 | } |
---|
173 | |
---|
174 | GMutex * |
---|
175 | linc_object_get_mutex (void) |
---|
176 | { |
---|
177 | return linc_lifecycle_mutex; |
---|
178 | } |
---|
179 | |
---|
180 | gpointer |
---|
181 | linc_object_ref (GObject *object) |
---|
182 | { |
---|
183 | gpointer ret; |
---|
184 | |
---|
185 | LINC_MUTEX_LOCK (linc_lifecycle_mutex); |
---|
186 | |
---|
187 | ret = g_object_ref (object); |
---|
188 | |
---|
189 | LINC_MUTEX_UNLOCK (linc_lifecycle_mutex); |
---|
190 | |
---|
191 | return ret; |
---|
192 | } |
---|
193 | |
---|
194 | void |
---|
195 | linc_object_unref (GObject *object) |
---|
196 | { |
---|
197 | gboolean last_ref; |
---|
198 | |
---|
199 | LINC_MUTEX_LOCK (linc_lifecycle_mutex); |
---|
200 | |
---|
201 | if (!(last_ref = (object->ref_count == 1))) |
---|
202 | g_object_unref (object); |
---|
203 | |
---|
204 | LINC_MUTEX_UNLOCK (linc_lifecycle_mutex); |
---|
205 | |
---|
206 | if (last_ref) /* take it outside the guard */ |
---|
207 | g_object_unref (object); |
---|
208 | } |
---|
209 | |
---|
210 | GMainLoop * |
---|
211 | linc_main_get_loop (void) |
---|
212 | { |
---|
213 | return linc_loop; |
---|
214 | } |
---|
215 | |
---|
216 | GMainContext * |
---|
217 | linc_main_get_context (void) |
---|
218 | { |
---|
219 | return linc_context; |
---|
220 | } |
---|