source: trunk/third/linc/src/linc.c @ 18552

Revision 18552, 4.9 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18551, which included commits to RCS files with non-trunk default branches.
Line 
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
16static gboolean linc_threaded = FALSE;
17static gboolean linc_mutex_new_called = FALSE;
18GMainLoop      *linc_loop = NULL;
19GMainContext   *linc_context = NULL;
20static GMutex  *linc_lifecycle_mutex = NULL;
21
22#ifdef LINC_SSL_SUPPORT
23SSL_METHOD *linc_ssl_method;
24SSL_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 **/
35void
36linc_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 **/
49void
50linc_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 **/
122void
123linc_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 **/
136gboolean
137linc_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 **/
147void
148linc_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 **/
161GMutex *
162linc_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
174GMutex *
175linc_object_get_mutex (void)
176{
177        return linc_lifecycle_mutex;
178}
179
180gpointer
181linc_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
194void
195linc_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
210GMainLoop *
211linc_main_get_loop (void)
212{
213        return linc_loop;
214}
215
216GMainContext *
217linc_main_get_context (void)
218{
219        return linc_context;
220}
Note: See TracBrowser for help on using the repository browser.