1 /*
2 * Warning - before reading this file, and while hacking
3 * it, it is advisable to examine:
4 *
5 * docs/internals/interface-indirection.gnumeric
6 *
7 * FIXME: We need some global I/F -> m_data lookup action
8 * FIXME: We need to map interface inheritance.
9 * FIXME: Add #ifdef ORBIT_PURIFY support.
10 *
11 * FIXME: 'Obvious' optimizations
12 * Here:
13 * * 2 demarshalers - 1 straight, 1 endianness switching.
14 * * do more alloca's for basic things
15 * * more IDL compiler help for allocation and indirection
16 * decisions - these are closely tied
17 * * No alias types in the structures ... nice :-)
18 * Elsewhere:
19 * * store object profiles in GIOP format for fast marshaling
20 * * make locking more chunky _T everything.
21 */
22
23 #include <config.h>
24 #include <sys/types.h>
25 #ifdef HAVE_UNISTD_H
26 # include <unistd.h>
27 #endif
28 #include <stdio.h>
29 #include <string.h>
30
31 #include <gmodule.h>
32 #include <glib.h>
33
34 #include <orbit/orbit.h>
35
36 #include "../poa/orbit-poa-export.h"
37 #include "../GIOP/giop-debug.h"
38 #include "orb-core-private.h"
39 #include "orbit-debug.h"
40
41 int ORBit_small_flags = 0;
42
43 gpointer
ORBit_small_alloc(CORBA_TypeCode tc)44 ORBit_small_alloc (CORBA_TypeCode tc)
45 {
46 return ORBit_alloc_by_tc (tc);
47 }
48
49 gpointer
ORBit_small_allocbuf(CORBA_TypeCode tc,CORBA_unsigned_long length)50 ORBit_small_allocbuf (CORBA_TypeCode tc, CORBA_unsigned_long length)
51 {
52 /* see above */
53 return ORBit_alloc_tcval (tc->subtypes [0], length);
54 }
55
56 void
ORBit_small_freekids(CORBA_TypeCode tc,gpointer p,gpointer d)57 ORBit_small_freekids (CORBA_TypeCode tc, gpointer p, gpointer d)
58 {
59 /* see above */
60 ORBit_freekids_via_TypeCode (tc, p);
61 }
62
63 static void
ORBit_handle_exception_array(GIOPRecvBuffer * rb,CORBA_Environment * ev,const ORBit_ITypes * types,CORBA_ORB orb)64 ORBit_handle_exception_array (GIOPRecvBuffer *rb,
65 CORBA_Environment *ev,
66 const ORBit_ITypes *types,
67 CORBA_ORB orb)
68 {
69 CORBA_SystemException *new;
70 CORBA_unsigned_long len, completion_status, reply_status;
71 CORBA_char *my_repoid;
72
73 g_return_if_fail (rb->msg.header.message_type == GIOP_REPLY);
74
75 CORBA_exception_free (ev);
76
77 rb->cur = ALIGN_ADDRESS (rb->cur, sizeof (len));
78 if ((rb->cur + 4) > rb->end)
79 goto errout;
80
81 len = *(CORBA_unsigned_long *)rb->cur;
82 rb->cur += 4;
83 if (giop_msg_conversion_needed (rb))
84 len = GUINT32_SWAP_LE_BE (len);
85
86 if (len) {
87 my_repoid = (char *) rb->cur;
88 rb->cur += len;
89 } else
90 my_repoid = NULL;
91
92 reply_status = giop_recv_buffer_reply_status (rb);
93
94 dprintf (MESSAGES, "Received exception %d: '%s'\n",
95 reply_status, my_repoid ? my_repoid : "<Null>");
96
97 if (reply_status == CORBA_SYSTEM_EXCEPTION) {
98 CORBA_unsigned_long minor;
99
100 dprintf (MESSAGES, "system exception\n");
101
102 ev->_major = CORBA_SYSTEM_EXCEPTION;
103
104 rb->cur = ALIGN_ADDRESS (rb->cur, sizeof (minor));
105 if ((rb->cur + sizeof (minor)) > rb->end)
106 goto errout;
107 minor = *(CORBA_unsigned_long *) rb->cur;
108 rb->cur += 4;
109 if (giop_msg_conversion_needed (rb))
110 minor = GUINT32_SWAP_LE_BE (minor);
111
112 rb->cur = ALIGN_ADDRESS (rb->cur, sizeof (completion_status));
113 if ((rb->cur + sizeof (completion_status)) > rb->end)
114 goto errout;
115 completion_status = *(CORBA_unsigned_long *) rb->cur;
116 rb->cur += 4;
117 if (giop_msg_conversion_needed (rb))
118 completion_status = GUINT32_SWAP_LE_BE (completion_status);
119
120 new = CORBA_SystemException__alloc ();
121 new->minor = minor;
122 new->completed = completion_status;
123
124 /* FIXME: check what should the repo ID be? */
125 CORBA_exception_set (ev, CORBA_SYSTEM_EXCEPTION,
126 my_repoid, new);
127 /* FIXME: might be fixed one day by cunning detection
128 in CORBA_exception_set ... */
129 if (!ev->_any._type)
130 ev->_any._type = ORBit_RootObject_duplicate (
131 TC_CORBA_SystemException);
132
133 dprintf (MESSAGES, "system exception de-marshaled\n");
134 return;
135
136 } else if (reply_status == CORBA_USER_EXCEPTION) {
137 int i;
138
139 dprintf (MESSAGES, "user exception\n");
140
141 for (i = 0; my_repoid && i < types->_length; i++) {
142 if (!strcmp (types->_buffer[i]->repo_id, my_repoid))
143 break;
144 }
145
146 if (!types || types->_length == 0 || i >= types->_length) {
147 /* weirdness; they raised an exception that we don't
148 know about */
149 CORBA_exception_set_system (
150 ev, ex_CORBA_MARSHAL,
151 CORBA_COMPLETED_MAYBE);
152 } else {
153 gpointer data;
154
155 dprintf (MESSAGES, "de-marshal user exception\n");
156
157 data = ORBit_demarshal_arg (
158 rb, types->_buffer [i], orb);
159
160 /* FIXME: might be fixed one day by cunning detection
161 in CORBA_exception_set ... */
162 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
163 types->_buffer [i]->repo_id, data);
164 if (!ev->_any._type)
165 ev->_any._type = ORBit_RootObject_duplicate (
166 types->_buffer [i]);
167 }
168 }
169
170 if (ev->_major != CORBA_NO_EXCEPTION)
171 return;
172
173 errout:
174 /* ignore LOCATION_FORWARD here, that gets handled in the stub */
175 CORBA_exception_set_system (ev, ex_CORBA_MARSHAL,
176 CORBA_COMPLETED_MAYBE);
177 }
178
179 static gboolean
ORBit_small_send_user_exception(GIOPSendBuffer * send_buffer,CORBA_Environment * ev,const ORBit_ITypes * types)180 ORBit_small_send_user_exception (GIOPSendBuffer *send_buffer,
181 CORBA_Environment *ev,
182 const ORBit_ITypes *types)
183 {
184 int i;
185
186 for (i = 0; i < types->_length; i++) {
187 if(!strcmp (types->_buffer[i]->repo_id, ev->_id))
188 break;
189 }
190
191 if (i >= types->_length) {
192 g_warning ("Some clown returned undeclared "
193 "exception '%s' ", ev->_id);
194
195 CORBA_exception_free (ev);
196 CORBA_exception_set_system (
197 ev, ex_CORBA_UNKNOWN,
198 CORBA_COMPLETED_MAYBE);
199
200 giop_send_buffer_unuse (send_buffer);
201
202 return FALSE;
203 } else {
204 giop_send_buffer_append_string (send_buffer, ev->_id);
205
206 dprintf (MESSAGES, "Returning exception of type '%s'\n", ev->_id);
207
208 ORBit_marshal_arg (send_buffer, ev->_any._value,
209 types->_buffer[i]);
210
211 return TRUE;
212 }
213 }
214
215 static void
ORBit_small_marshal_context(GIOPSendBuffer * send_buffer,ORBit_IMethod * m_data,CORBA_Context ctx)216 ORBit_small_marshal_context (GIOPSendBuffer *send_buffer,
217 ORBit_IMethod *m_data,
218 CORBA_Context ctx)
219 {
220 int i;
221 /* Horrible inefficiency to get round the 'lete
222 efficiency of the current impl */
223 ORBit_ContextMarshalItem *mlist;
224
225 mlist = g_alloca (sizeof (ORBit_ContextMarshalItem) *
226 m_data->contexts._length);
227
228 tprintf (" context { ");
229
230 for (i = 0; i < m_data->contexts._length; i++) {
231 char *val;
232
233 mlist [i].str = m_data->contexts._buffer [i];
234
235 val = g_hash_table_lookup (ctx->mappings, mlist [i].str);
236 tprintf ("( %s: '%s' )%s", mlist [i].str, val,
237 i < m_data->contexts._length - 1 ? ", ": "");
238
239 mlist [i].len = strlen (mlist [i].str) + 1;
240 }
241
242 tprintf (" }");
243
244 /* Assumption, this doesn't whack mlist pointers into
245 the send_buffer: verified */
246 ORBit_Context_marshal (
247 ctx, mlist, m_data->contexts._length, send_buffer);
248 }
249
250 #define BASE_TYPES \
251 CORBA_tk_short: \
252 case CORBA_tk_long: \
253 case CORBA_tk_enum: \
254 case CORBA_tk_ushort: \
255 case CORBA_tk_ulong: \
256 case CORBA_tk_float: \
257 case CORBA_tk_double: \
258 case CORBA_tk_boolean: \
259 case CORBA_tk_char: \
260 case CORBA_tk_octet: \
261 case CORBA_tk_longlong: \
262 case CORBA_tk_ulonglong: \
263 case CORBA_tk_longdouble: \
264 case CORBA_tk_wchar
265
266 #define STRUCT_UNION_TYPES \
267 CORBA_tk_struct: \
268 case CORBA_tk_union: \
269 case CORBA_tk_except
270
271 #define OBJ_STRING_TYPES \
272 CORBA_tk_objref: \
273 case CORBA_tk_TypeCode: \
274 case CORBA_tk_string: \
275 case CORBA_tk_wstring
276
277 #define SEQ_ANY_TYPES \
278 CORBA_tk_sequence: \
279 case CORBA_tk_any
280
281 typedef struct {
282 CORBA_unsigned_long len;
283 char opname[1];
284 } OpData;
285
286 #define do_marshal_value(a,b,c) \
287 ORBit_marshal_value ((a),(gconstpointer *)(b),(c))
288 #define do_demarshal_value(a,b,c,e) \
289 if (ORBit_demarshal_value ((c),(b),(a),(e))) \
290 goto demarshal_exception
291
292 static gboolean
orbit_small_marshal(CORBA_Object obj,GIOPConnection * cnx,GIOPMessageQueueEntry * mqe,CORBA_unsigned_long request_id,ORBit_IMethod * m_data,gpointer * args,CORBA_Context ctx)293 orbit_small_marshal (CORBA_Object obj,
294 GIOPConnection *cnx,
295 GIOPMessageQueueEntry *mqe,
296 CORBA_unsigned_long request_id,
297 ORBit_IMethod *m_data,
298 gpointer *args,
299 CORBA_Context ctx)
300 {
301 GIOPSendBuffer *send_buffer;
302 struct iovec op_vec;
303 CORBA_TypeCode tc;
304 int i;
305
306 tprintf_header (obj, m_data);
307
308 {
309 int align;
310 int len = sizeof (CORBA_unsigned_long) + m_data->name_len + 1;
311 guchar *header = g_alloca (len + sizeof (CORBA_unsigned_long));
312
313 *(CORBA_unsigned_long *) header = m_data->name_len + 1;
314 memcpy (header + sizeof (CORBA_unsigned_long),
315 m_data->name, m_data->name_len + 1);
316
317 align = len + (sizeof (CORBA_unsigned_long) - 1);
318 align &= ~(sizeof (CORBA_unsigned_long) - 1);
319 memset (header + len, 0, align - len);
320
321 dprintf (MESSAGES, "Align = %d\n", align);
322 op_vec.iov_len = align;
323 op_vec.iov_base = header;
324 }
325
326 send_buffer = giop_send_buffer_use_request (
327 cnx->giop_version, request_id,
328 (m_data->flags & ORBit_I_METHOD_1_WAY) == 0,
329 obj->object_key, &op_vec, NULL);
330
331 if (!send_buffer)
332 return FALSE;
333
334 dprintf (MESSAGES, "Marshal: id 0x%x\n", request_id);
335
336 for (i = 0; i < m_data->arguments._length; i++) {
337
338 ORBit_IArg *a = &m_data->arguments._buffer [i];
339 gpointer p;
340
341 if (!(a->flags & (ORBit_I_ARG_IN |
342 ORBit_I_ARG_INOUT)))
343 continue;
344 tc = a->tc;
345
346 while (tc->kind == CORBA_tk_alias)
347 tc = tc->subtypes [0];
348
349 dump_arg (a, tc);
350
351 p = args [i];
352 tprintf_trace_value (&p, tc);
353
354 p = args [i];
355 do_marshal_value (send_buffer, &p, tc);
356
357 if (i < m_data->arguments._length - 1)
358 tprintf (", ");
359 }
360
361 tprintf (")");
362
363 if (m_data->contexts._length > 0)
364 ORBit_small_marshal_context (send_buffer, m_data, ctx);
365
366 do_giop_dump_send (send_buffer);
367
368 if (giop_send_buffer_write (send_buffer, cnx, FALSE)) {
369 g_warning ("Failed to send buffer");
370 giop_recv_list_destroy_queue_entry (mqe);
371 return FALSE;
372 }
373
374 giop_send_buffer_unuse (send_buffer);
375
376 return TRUE;
377 }
378
379 typedef enum {
380 MARSHAL_SYS_EXCEPTION_INCOMPLETE,
381 MARSHAL_SYS_EXCEPTION_COMPLETE,
382 MARSHAL_EXCEPTION_COMPLETE,
383 MARSHAL_RETRY,
384 MARSHAL_CLEAN
385 } DeMarshalRetType;
386
387 static DeMarshalRetType
orbit_small_demarshal(CORBA_Object obj,GIOPConnection ** cnx,GIOPRecvBuffer * recv_buffer,CORBA_Environment * ev,gpointer ret,ORBit_IMethod * m_data,gpointer * args)388 orbit_small_demarshal (CORBA_Object obj,
389 GIOPConnection **cnx,
390 GIOPRecvBuffer *recv_buffer,
391 CORBA_Environment *ev,
392 gpointer ret,
393 ORBit_IMethod *m_data,
394 gpointer *args)
395 {
396 gpointer data, p;
397 CORBA_TypeCode tc;
398 CORBA_ORB orb = obj->orb;
399
400 if (!recv_buffer) {
401 dprintf (MESSAGES, "No recv buffer ...\n");
402 return MARSHAL_SYS_EXCEPTION_INCOMPLETE;
403 }
404
405 if (giop_recv_buffer_reply_status (recv_buffer) != GIOP_NO_EXCEPTION)
406 goto msg_exception;
407
408 if ((tc = m_data->ret) && tc->kind != CORBA_tk_void) {
409 tprintf (" =>: ");
410
411 g_assert (ret != NULL);
412
413 while (tc->kind == CORBA_tk_alias)
414 tc = tc->subtypes [0];
415
416 switch (tc->kind) {
417 case BASE_TYPES:
418 case OBJ_STRING_TYPES:
419 p = ret;
420 do_demarshal_value (recv_buffer, &ret, tc, orb);
421 tprintf_trace_value (&p, tc);
422 break;
423
424 case STRUCT_UNION_TYPES:
425 if (m_data->flags & ORBit_I_COMMON_FIXED_SIZE) {
426 p = ret;
427 do_demarshal_value (recv_buffer, &ret, tc, orb);
428 tprintf_trace_value (&p, tc);
429 break;
430 } /* drop through */
431
432 case SEQ_ANY_TYPES:
433 case CORBA_tk_array:
434 default:
435 data = ORBit_demarshal_arg (recv_buffer, tc, orb);
436 if (!data)
437 return MARSHAL_SYS_EXCEPTION_COMPLETE;
438
439 p = data;
440 tprintf_trace_value (&p, tc);
441
442 *((gpointer *)ret) = data;
443 break;
444 }
445 }
446
447 {
448 int i;
449 int trace_have_out = 0;
450
451 for (i = 0; i < m_data->arguments._length; i++) {
452 const ORBit_IArg *a;
453 gpointer arg;
454
455 a = &m_data->arguments._buffer [i];
456
457 if (!(a->flags & (ORBit_I_ARG_OUT |
458 ORBit_I_ARG_INOUT)))
459 continue;
460
461 tc = a->tc;
462
463 while (tc->kind == CORBA_tk_alias)
464 tc = tc->subtypes [0];
465
466 dump_arg (a, tc);
467
468 if (a->flags & ORBit_I_ARG_OUT)
469 /* this may read (&discard) uninitialized memory,
470 * see 'foo' below. This is for simplicity. */
471 arg = *(gpointer *)args [i];
472 else
473 arg = args [i];
474
475 switch (tc->kind) {
476 case OBJ_STRING_TYPES: {
477 if (a->flags & ORBit_I_ARG_INOUT) {
478 if (tc->kind == CORBA_tk_TypeCode ||
479 tc->kind == CORBA_tk_objref)
480 CORBA_Object_release (*(gpointer *)arg, ev);
481 else if (tc->kind == CORBA_tk_string ||
482 tc->kind == CORBA_tk_wstring)
483 ORBit_free (*(gpointer *) arg);
484 }
485 /* drop through */
486 case BASE_TYPES:
487 if (!trace_have_out++)
488 tprintf (" out: (");
489 p = arg;
490 do_demarshal_value (recv_buffer, &arg, tc, orb);
491 tprintf_trace_value (&p, tc);
492 break;
493 }
494
495 case STRUCT_UNION_TYPES:
496 case SEQ_ANY_TYPES:
497 case CORBA_tk_array:
498 default:
499 p = arg;
500 if (a->flags & ORBit_I_COMMON_FIXED_SIZE) {
501 do_demarshal_value (recv_buffer, &arg, tc, orb);
502 } else if (a->flags & ORBit_I_ARG_INOUT) {
503 ORBit_freekids_via_TypeCode (tc, arg);
504 do_demarshal_value (recv_buffer, &arg, tc, orb);
505 } else /* 'foo' - don't use the bogus 'arg' contents */
506 *(gpointer *)args [i] = p = ORBit_demarshal_arg (
507 recv_buffer, tc, obj->orb);
508
509 if (!trace_have_out++)
510 tprintf (" out: (");
511 tprintf_trace_value (&p, tc);
512 break;
513 }
514 if (trace_have_out &&
515 i < m_data->arguments._length - 1)
516 tprintf (", ");
517 }
518 if (trace_have_out)
519 tprintf (" )");
520 }
521
522 return MARSHAL_CLEAN;
523
524 demarshal_exception:
525 /* FIXME: may well leak */
526 CORBA_exception_set_system(ev, ex_CORBA_MARSHAL,
527 CORBA_COMPLETED_MAYBE);
528 return MARSHAL_EXCEPTION_COMPLETE;
529
530 msg_exception:
531 if (giop_recv_buffer_reply_status (recv_buffer) ==
532 GIOP_LOCATION_FORWARD) {
533
534 *cnx = ORBit_handle_location_forward (recv_buffer, obj);
535 tprintf (" Exception: forward (%p)", *cnx);
536 if (!*cnx) {
537 CORBA_exception_set_system(ev, ex_CORBA_MARSHAL,
538 CORBA_COMPLETED_MAYBE);
539 return MARSHAL_SYS_EXCEPTION_INCOMPLETE;
540 }
541 return MARSHAL_RETRY;
542 } else {
543 ORBit_handle_exception_array (
544 recv_buffer, ev, &m_data->exceptions, obj->orb);
545
546 #ifdef G_ENABLE_DEBUG
547 if (_orbit_debug_flags & ORBIT_DEBUG_TRACES) {
548 if (ev->_major == CORBA_SYSTEM_EXCEPTION)
549 tprintf (" System Exception: '%s' ", ev->_id);
550 else {
551 tprintf (" User Exception: '%s' ", ev->_id);
552 ORBit_trace_any (&ev->_any);
553 }
554 }
555 #endif /* G_ENABLE_DEBUG */
556
557 return MARSHAL_EXCEPTION_COMPLETE;
558 }
559 }
560
561 void
ORBit_small_invoke_stub_n(CORBA_Object object,ORBit_IMethods * methods,glong index,gpointer ret,gpointer * args,CORBA_Context ctx,CORBA_Environment * ev)562 ORBit_small_invoke_stub_n (CORBA_Object object,
563 ORBit_IMethods *methods,
564 glong index,
565 gpointer ret,
566 gpointer *args,
567 CORBA_Context ctx,
568 CORBA_Environment *ev)
569 {
570 if (index < 0 || index > methods->_length) {
571 dprintf (MESSAGES, "Cannot invoke OOB method (%ld,%lu)\n",
572 index, (gulong)methods->_length);
573 CORBA_exception_set_system (ev, ex_CORBA_NO_IMPLEMENT,
574 CORBA_COMPLETED_NO);
575
576 } else
577 ORBit_small_invoke_stub (object, &methods->_buffer[index], ret, args, ctx, ev);
578 }
579
580 void
ORBit_small_invoke_stub(CORBA_Object obj,ORBit_IMethod * m_data,gpointer ret,gpointer * args,CORBA_Context ctx,CORBA_Environment * ev)581 ORBit_small_invoke_stub (CORBA_Object obj,
582 ORBit_IMethod *m_data,
583 gpointer ret,
584 gpointer *args,
585 CORBA_Context ctx,
586 CORBA_Environment *ev)
587 {
588 CORBA_unsigned_long request_id;
589 CORBA_completion_status completion_status;
590 GIOPConnection *cnx = NULL;
591 GIOPMessageQueueEntry mqe;
592 ORBit_OAObject adaptor_obj;
593 GIOPRecvBuffer *recv_buffer = NULL;
594 CORBA_Object xt_proxy = CORBA_OBJECT_NIL;
595 ORBitPolicy *invoke_policy = CORBA_OBJECT_NIL;
596 gboolean timeout = FALSE;
597
598 CORBA_exception_init (ev);
599
600 if (!obj) {
601 dprintf (MESSAGES, "Cannot invoke method on null object\n");
602 CORBA_exception_set_system (ev, ex_CORBA_INV_OBJREF,
603 CORBA_COMPLETED_NO);
604 goto clean_out;
605 }
606
607 if ((invoke_policy = ORBit_object_get_policy (obj)))
608 ORBit_policy_push (invoke_policy);
609
610 adaptor_obj = obj->adaptor_obj;
611
612 if (adaptor_obj) {
613 /* FIXME: unchecked cast */
614 if (ORBit_poa_allow_cross_thread_call ((ORBit_POAObject) adaptor_obj,
615 m_data->flags)) {
616 tprintf_header (obj, m_data);
617 tprintf ("[in-proc]");
618 ORBit_small_handle_request (adaptor_obj, m_data->name, ret,
619 args, ctx, NULL, ev);
620 goto clean_out;
621 } else {
622 tprintf ("[in-proc-XT]");
623 /*
624 * FIXME: this is _really_ slow, can easily be optimised
625 * by shoving the GIOP data straight on the incoming
626 * queue
627 */
628 xt_proxy = ORBit_objref_get_proxy (obj);
629 obj = xt_proxy;
630 }
631 } else
632 giop_thread_new_check (NULL);
633
634 cnx = ORBit_object_get_connection (obj);
635
636 if (!cnx) {
637 dprintf (MESSAGES, "Null connection on object '%p'\n", obj);
638 completion_status = CORBA_COMPLETED_NO;
639 goto system_exception;
640 }
641
642 retry_request:
643 request_id = GPOINTER_TO_UINT (&obj);
644 completion_status = CORBA_COMPLETED_NO;
645
646 giop_recv_list_setup_queue_entry (&mqe, cnx, GIOP_REPLY, request_id);
647
648 if (!orbit_small_marshal (obj, cnx, &mqe, request_id,
649 m_data, args, ctx))
650 goto system_exception;
651
652 completion_status = CORBA_COMPLETED_MAYBE;
653
654 if (m_data->flags & ORBit_I_METHOD_1_WAY) {
655 tprintf ("[ one way ]");
656 giop_recv_list_destroy_queue_entry (&mqe);
657 goto clean_out;
658 }
659
660 recv_buffer = giop_recv_buffer_get (&mqe, &timeout);
661 if (timeout)
662 goto timeout_exception;
663
664 switch (orbit_small_demarshal (obj, &cnx, recv_buffer, ev,
665 ret, m_data, args))
666 {
667 case MARSHAL_SYS_EXCEPTION_COMPLETE:
668 completion_status = CORBA_COMPLETED_YES;
669 dprintf (MESSAGES, "Sys exception completed on id 0x%x\n\n", request_id);
670 goto system_exception;
671
672 case MARSHAL_SYS_EXCEPTION_INCOMPLETE:
673 dprintf (MESSAGES, "Sys exception incomplete on id 0x%x\n\n", request_id);
674 goto system_exception;
675
676 case MARSHAL_EXCEPTION_COMPLETE:
677 dprintf (MESSAGES, "Clean demarshal of exception on id 0x%x\n\n", request_id);
678 break;
679
680 case MARSHAL_RETRY:
681 dprintf (MESSAGES, "Retry demarshal on id 0x%x\n\n", request_id);
682 goto retry_request;
683
684 case MARSHAL_CLEAN:
685 dprintf (MESSAGES, "Clean demarshal on id 0x%x\n\n", request_id);
686 break;
687 };
688
689 clean_out:
690 ORBit_RootObject_release (xt_proxy);
691 giop_recv_buffer_unuse (recv_buffer);
692
693 tprintf_end_method ();
694 if (cnx)
695 giop_connection_unref (cnx);
696 if (invoke_policy) {
697 ORBit_policy_pop ();
698 ORBit_policy_unref (invoke_policy);
699 }
700 return;
701
702 system_exception:
703 tprintf ("[System exception comm failure] )");
704 CORBA_exception_set_system (ev, ex_CORBA_COMM_FAILURE,
705 completion_status);
706 goto clean_out;
707
708 timeout_exception:
709 tprintf ("[System exception timeout] )");
710 CORBA_exception_set_system (ev, ex_CORBA_TIMEOUT,
711 CORBA_COMPLETED_NO);
712 goto clean_out;
713 }
714
715 void
ORBit_small_invoke_adaptor(ORBit_OAObject adaptor_obj,GIOPRecvBuffer * recv_buffer,ORBit_IMethod * m_data,gpointer data,CORBA_Environment * ev)716 ORBit_small_invoke_adaptor (ORBit_OAObject adaptor_obj,
717 GIOPRecvBuffer *recv_buffer,
718 ORBit_IMethod *m_data,
719 gpointer data,
720 CORBA_Environment *ev)
721 {
722 struct CORBA_Context_type ctx;
723 gpointer *args = NULL;
724 gpointer *scratch = NULL;
725 gpointer pretval = NULL;
726 gpointer retval = NULL;
727 GIOPSendBuffer *send_buffer;
728 CORBA_ORB orb;
729 CORBA_TypeCode tc;
730 gboolean has_context;
731 int i;
732
733 orb = ((ORBit_POAObject)adaptor_obj)->poa->orb;
734
735 has_context = (m_data->contexts._length > 0);
736
737 tprintf_header (adaptor_obj->objref, m_data);
738
739 if ((tc = m_data->ret) && tc->kind != CORBA_tk_void) {
740
741 while (tc->kind == CORBA_tk_alias)
742 tc = tc->subtypes [0];
743
744 switch (tc->kind) {
745 case BASE_TYPES:
746 case OBJ_STRING_TYPES:
747 retval = g_alloca (ORBit_gather_alloc_info (tc));
748 break;
749 case STRUCT_UNION_TYPES:
750 if (m_data->flags & ORBit_I_COMMON_FIXED_SIZE) {
751 retval = ORBit_alloc_by_tc (tc);
752 break;
753 } /* drop through */
754 default:
755 retval = &pretval;
756 pretval = NULL;
757 break;
758 }
759 }
760
761 if (m_data->arguments._length > 0) {
762 int len = m_data->arguments._length *
763 sizeof (gpointer);
764
765 args = g_alloca (len);
766 memset (args, 0, len);
767 scratch = g_alloca (len);
768 memset (scratch, 0, len);
769 }
770
771 for (i = 0; i < m_data->arguments._length; i++) {
772 ORBit_IArg *a = &m_data->arguments._buffer [i];
773
774 if (a->flags & ORBit_I_ARG_IN ||
775 a->flags & ORBit_I_ARG_INOUT) {
776 gpointer p;
777
778 tc = a->tc;
779
780 while (tc->kind == CORBA_tk_alias)
781 tc = tc->subtypes [0];
782
783 switch (tc->kind) {
784 case BASE_TYPES:
785 case OBJ_STRING_TYPES:
786 p = args [i] = g_alloca (ORBit_gather_alloc_info (tc));
787 do_demarshal_value (recv_buffer, &p, tc, orb);
788
789 p = args [i];
790 tprintf_trace_value (&p, tc);
791 break;
792 case STRUCT_UNION_TYPES:
793 case CORBA_tk_array:
794 if (a->flags & ORBit_I_COMMON_FIXED_SIZE) {
795 p = args [i] = g_alloca (ORBit_gather_alloc_info (tc));
796 do_demarshal_value (recv_buffer, &p, tc, orb);
797 p = args [i];
798 tprintf_trace_value (&p, tc);
799 break;
800 } /* drop through */
801 default:
802 args [i] = ORBit_demarshal_arg (recv_buffer, a->tc, orb);
803 p = args [i];
804 tprintf_trace_value (&p, tc);
805 break;
806 }
807
808 } else { /* Out */
809 tc = a->tc;
810
811 while (tc->kind == CORBA_tk_alias)
812 tc = tc->subtypes [0];
813
814 args [i] = &scratch [i];
815
816 switch (tc->kind) {
817 case BASE_TYPES:
818 case OBJ_STRING_TYPES:
819 scratch [i] = g_alloca (ORBit_gather_alloc_info (tc));
820 break;
821 case STRUCT_UNION_TYPES:
822 case CORBA_tk_array:
823 if (a->flags & ORBit_I_COMMON_FIXED_SIZE) {
824 scratch [i] = ORBit_alloc_by_tc (tc);
825 break;
826 } /* drop through */
827 default:
828 scratch [i] = NULL;
829 break;
830 }
831
832 }
833
834 if (i < m_data->arguments._length - 1)
835 tprintf (", ");
836 }
837
838 tprintf (")");
839
840 if (has_context) {
841 tprintf ("[FIXME:context]");
842 if (ORBit_Context_demarshal (NULL, &ctx, recv_buffer))
843 g_warning ("FIXME: handle context demarshaling failure");
844 }
845
846 ORBit_OAObject_invoke (adaptor_obj, retval, args, &ctx, data, ev);
847
848 if (has_context)
849 ORBit_Context_server_free (&ctx);
850
851 if (m_data->flags & ORBit_I_METHOD_1_WAY)
852 goto clean_out;
853 else
854 goto handle_possible_exception;
855
856 demarshal_exception:
857 CORBA_exception_set_system (ev, ex_CORBA_MARSHAL,
858 CORBA_COMPLETED_NO);
859
860 handle_possible_exception:
861 /* FIXME: should we be using the connection's GIOP version ? */
862 send_buffer = giop_send_buffer_use_reply (
863 recv_buffer->giop_version,
864 giop_recv_buffer_get_request_id (recv_buffer),
865 ev->_major);
866
867 if (!send_buffer) {
868 dprintf (MESSAGES, "Weird, no send_buffer");
869 return;
870
871 } else if (ev->_major == CORBA_USER_EXCEPTION) {
872 if (!ORBit_small_send_user_exception (
873 send_buffer, ev, &m_data->exceptions)) {
874 /* Tried to marshal an unknown exception,
875 so we throw a system exception next */
876 dprintf (MESSAGES, "Re-sending an exception, this time %d: '%s'",
877 ev->_major, ev->_id);
878 goto handle_possible_exception;
879 }
880 tprintf ("User exception '%s'", ev->_id);
881
882 } else if (ev->_major != CORBA_NO_EXCEPTION) {
883 ORBit_send_system_exception (send_buffer, ev);
884
885 tprintf ("System exception");
886
887 } else { /* Marshal return values */
888 int trace_have_out = 0;
889
890 if ((tc = m_data->ret) && tc->kind != CORBA_tk_void) {
891 gpointer p = retval;
892
893 tprintf (" =>; ");
894
895 while (tc->kind == CORBA_tk_alias)
896 tc = tc->subtypes [0];
897
898 switch (tc->kind) {
899
900 case BASE_TYPES:
901 case OBJ_STRING_TYPES:
902 ORBit_marshal_arg (send_buffer, retval, m_data->ret);
903 tprintf_trace_value (&p, tc);
904 break;
905
906 case STRUCT_UNION_TYPES:
907 if (m_data->flags & ORBit_I_COMMON_FIXED_SIZE) {
908 ORBit_marshal_arg (send_buffer, retval, m_data->ret);
909 tprintf_trace_value (&p, tc);
910 break;
911 } /* drop through */
912
913 case CORBA_tk_any:
914 case CORBA_tk_sequence:
915 case CORBA_tk_array:
916 default:
917 p = *(gpointer *) retval;
918 ORBit_marshal_arg (send_buffer, *(gpointer *)retval, m_data->ret);
919 tprintf_trace_value (&p, tc);
920 break;
921 }
922 }
923
924 for (i = 0; i < m_data->arguments._length; i++) {
925 ORBit_IArg *a = &m_data->arguments._buffer [i];
926 gpointer p;
927
928 tc = a->tc;
929 while (tc->kind == CORBA_tk_alias)
930 tc = tc->subtypes [0];
931
932 if (a->flags & ORBit_I_ARG_INOUT) {
933 if (!trace_have_out++)
934 tprintf (" out: (");
935
936 ORBit_marshal_arg (send_buffer, args [i], tc);
937 p = args [i];
938 tprintf_trace_value (&p, tc);
939 }
940
941 else if (a->flags & ORBit_I_ARG_OUT) {
942 if (!trace_have_out++)
943 tprintf (" out: (");
944
945 ORBit_marshal_arg (send_buffer, scratch [i], tc);
946
947 p = scratch [i];
948 tprintf_trace_value (&p, tc);
949 }
950
951 if (trace_have_out &&
952 i < m_data->arguments._length - 1 &&
953 m_data->arguments._buffer [i + 1].flags &
954 (ORBit_I_ARG_OUT | ORBit_I_ARG_INOUT))
955 tprintf (", ");
956 }
957 if (trace_have_out)
958 tprintf (" )");
959 }
960
961 do_giop_dump_send (send_buffer);
962
963 giop_send_buffer_write (send_buffer, recv_buffer->connection, FALSE);
964 giop_send_buffer_unuse (send_buffer);
965
966 if (m_data->ret && tc->kind != CORBA_tk_void) {
967 switch (m_data->ret->kind) {
968 case BASE_TYPES:
969 break;
970 case CORBA_tk_objref:
971 case CORBA_tk_TypeCode:
972 if (ev->_major == CORBA_NO_EXCEPTION)
973 CORBA_Object_release (*(CORBA_Object *) retval, ev);
974 break;
975 case CORBA_tk_string:
976 case CORBA_tk_wstring:
977 if (ev->_major == CORBA_NO_EXCEPTION)
978 ORBit_free (*(char **) retval);
979 break;
980 case STRUCT_UNION_TYPES:
981 if (m_data->flags & ORBit_I_COMMON_FIXED_SIZE) {
982 ORBit_free (retval);
983 break;
984 } /* drop through */
985 default:
986 if (ev->_major == CORBA_NO_EXCEPTION)
987 ORBit_free (pretval);
988 break;
989 }
990 }
991
992 clean_out:
993 tprintf_end_method ();
994
995 for (i = 0; i < m_data->arguments._length; i++) {
996 ORBit_IArg *a = &m_data->arguments._buffer [i];
997
998 tc = a->tc;
999
1000 while (tc->kind == CORBA_tk_alias)
1001 tc = tc->subtypes [0];
1002
1003 if (a->flags & ORBit_I_ARG_IN ||
1004 a->flags & ORBit_I_ARG_INOUT) {
1005
1006 switch (tc->kind) {
1007 case BASE_TYPES:
1008 break;
1009 case CORBA_tk_objref:
1010 case CORBA_tk_TypeCode:
1011 CORBA_Object_release (*(CORBA_Object *) args [i], ev);
1012 break;
1013 case CORBA_tk_string:
1014 case CORBA_tk_wstring:
1015 ORBit_free (*(char **) args [i]);
1016 break;
1017 case STRUCT_UNION_TYPES:
1018 case CORBA_tk_array:
1019 if (a->flags & ORBit_I_COMMON_FIXED_SIZE) {
1020 ORBit_freekids_via_TypeCode (tc, args [i]);
1021 break;
1022 }
1023 /* drop through */
1024 default:
1025 ORBit_free (args [i]);
1026 break;
1027 }
1028 } else { /* Out */
1029 switch (tc->kind) {
1030 case BASE_TYPES:
1031 break;
1032 case CORBA_tk_objref:
1033 case CORBA_tk_TypeCode:
1034 if (ev->_major == CORBA_NO_EXCEPTION)
1035 CORBA_Object_release (*(CORBA_Object *) scratch [i], ev);
1036 break;
1037 case CORBA_tk_string:
1038 case CORBA_tk_wstring:
1039 if (ev->_major == CORBA_NO_EXCEPTION)
1040 ORBit_free (*(char **) scratch [i]);
1041 break;
1042 case STRUCT_UNION_TYPES:
1043 case CORBA_tk_array:
1044 if (a->flags & ORBit_I_COMMON_FIXED_SIZE) {
1045 ORBit_free (scratch [i]);
1046 break;
1047 }
1048 /* drop through */
1049 default:
1050 if (ev->_major == CORBA_NO_EXCEPTION)
1051 ORBit_free (scratch [i]);
1052 break;
1053 }
1054 }
1055 }
1056
1057 CORBA_exception_free (ev);
1058 }
1059
1060 #ifdef DEBUG
1061 gpointer
ORBit_small_getepv(CORBA_Object obj,CORBA_unsigned_long class_id)1062 ORBit_small_getepv (CORBA_Object obj, CORBA_unsigned_long class_id)
1063 {
1064 PortableServer_ServantBase *servant;
1065 PortableServer_ClassInfo *class_info;
1066 CORBA_unsigned_long offset;
1067 ORBit_POAObject pobj;
1068
1069 if (obj->adaptor_obj->interface->adaptor_type != ORBIT_ADAPTOR_POA)
1070 return NULL;
1071
1072 pobj = (ORBit_POAObject)obj->adaptor_obj;
1073 servant = pobj->servant;
1074 class_info = servant->vepv[0]->_private;
1075 g_assert (class_info != NULL);
1076 g_assert (class_id < class_info->vepvlen);
1077 offset = class_info->vepvmap [class_id];
1078
1079 return servant->vepv [offset];
1080 }
1081 #endif
1082
1083 struct _ORBitAsyncQueueEntry {
1084 GIOPMessageQueueEntry mqe;
1085 CORBA_Object obj;
1086 ORBitAsyncInvokeFunc fn;
1087 gpointer user_data;
1088 ORBit_IMethod *m_data;
1089 CORBA_completion_status completion_status;
1090 };
1091
1092 void
ORBit_small_demarshal_async(ORBitAsyncQueueEntry * aqe,gpointer ret,gpointer * args,CORBA_Environment * ev)1093 ORBit_small_demarshal_async (ORBitAsyncQueueEntry *aqe,
1094 gpointer ret,
1095 gpointer *args,
1096 CORBA_Environment *ev)
1097 {
1098 g_return_if_fail (aqe->mqe.buffer != NULL);
1099
1100 switch (orbit_small_demarshal (aqe->obj, &aqe->mqe.cnx, aqe->mqe.buffer, ev,
1101 ret, aqe->m_data, args)) {
1102 case MARSHAL_SYS_EXCEPTION_COMPLETE:
1103 aqe->completion_status = CORBA_COMPLETED_YES;
1104 dprintf (MESSAGES, "Sys exception completed on id 0x%x\n\n",
1105 aqe->mqe.request_id);
1106 goto system_exception;
1107
1108 case MARSHAL_SYS_EXCEPTION_INCOMPLETE:
1109 dprintf (MESSAGES, "Sys exception incomplete on id 0x%x\n\n",
1110 aqe->mqe.request_id);
1111 goto system_exception;
1112
1113 case MARSHAL_EXCEPTION_COMPLETE:
1114 dprintf (MESSAGES, "Clean demarshal of exception on id 0x%x\n\n",
1115 aqe->mqe.request_id);
1116 break;
1117
1118 case MARSHAL_RETRY:
1119 g_warning ("Retry demarshal failed on id 0x%x\n\n", aqe->mqe.request_id);
1120 return;
1121
1122 case MARSHAL_CLEAN:
1123 dprintf (MESSAGES, "Clean demarshal on id 0x%x\n\n",
1124 aqe->mqe.request_id);
1125 break;
1126 };
1127 goto clean_out;
1128
1129 system_exception:
1130 tprintf ("[System exception comm failure] )");
1131 CORBA_exception_set_system (ev, ex_CORBA_COMM_FAILURE,
1132 aqe->completion_status);
1133
1134 clean_out:
1135 tprintf_end_method ();
1136 }
1137
1138 static void
async_recv_cb(ORBitAsyncQueueEntry * aqe)1139 async_recv_cb (ORBitAsyncQueueEntry *aqe)
1140 {
1141 CORBA_Environment *ev, real_ev;
1142
1143 ev = &real_ev;
1144 CORBA_exception_init (ev);
1145
1146 /* So we don't get invoked again */
1147 aqe->mqe.async_cb = NULL;
1148
1149 if (!aqe->mqe.cnx ||
1150 aqe->mqe.cnx->parent.status == LINK_DISCONNECTED)
1151 CORBA_exception_set_system (ev, ex_CORBA_COMM_FAILURE,
1152 aqe->completion_status);
1153
1154 if (aqe->mqe.cnx &&
1155 aqe->mqe.cnx->parent.status == LINK_TIMEOUT)
1156 CORBA_exception_set_system (ev, ex_CORBA_TIMEOUT,
1157 aqe->completion_status);
1158
1159 if (aqe->fn)
1160 aqe->fn (aqe->obj, aqe->m_data, aqe, aqe->user_data, ev);
1161
1162 ORBit_RootObject_release (aqe->obj);
1163 /* ORBit_RootObject_release (aqe->m_data); */
1164 giop_recv_list_destroy_queue_entry (&aqe->mqe);
1165 g_free (aqe);
1166 CORBA_exception_free (ev);
1167 }
1168
1169 /**
1170 * ORBit_small_invoke_async:
1171 * @obj:
1172 * @m_data:
1173 * @fn:
1174 * @user_data:
1175 * @args:
1176 * @ctx:
1177 * @ev:
1178 *
1179 * This method is used to invoke a remote (or local) method
1180 * asynchronously. @fn is called back on return - either with an empty
1181 * CORBA_Environment indicating success, or with the error.
1182 **/
1183 void
ORBit_small_invoke_async(CORBA_Object obj,ORBit_IMethod * m_data,ORBitAsyncInvokeFunc fn,gpointer user_data,gpointer * args,CORBA_Context ctx,CORBA_Environment * ev)1184 ORBit_small_invoke_async (CORBA_Object obj,
1185 ORBit_IMethod *m_data,
1186 ORBitAsyncInvokeFunc fn,
1187 gpointer user_data,
1188 gpointer *args,
1189 CORBA_Context ctx,
1190 CORBA_Environment *ev)
1191 {
1192 CORBA_unsigned_long request_id;
1193 GIOPConnection *cnx;
1194 ORBitAsyncQueueEntry *aqe = g_new (ORBitAsyncQueueEntry, 1);
1195
1196 if (obj->adaptor_obj) /* a local object, we need a remote handle */
1197 aqe->obj = ORBit_objref_get_proxy (obj);
1198 else
1199 aqe->obj = ORBit_RootObject_duplicate (obj);
1200
1201 cnx = ORBit_object_get_connection (aqe->obj);
1202
1203 if (!cnx) {
1204 tprintf ("Null connection on object '%p'\n", aqe->obj);
1205 aqe->completion_status = CORBA_COMPLETED_NO;
1206 goto system_exception;
1207 }
1208
1209 request_id = GPOINTER_TO_UINT (aqe);
1210 aqe->completion_status = CORBA_COMPLETED_NO;
1211
1212 giop_recv_list_setup_queue_entry (&aqe->mqe, cnx, GIOP_REPLY, request_id);
1213
1214 if (! (m_data->flags & ORBit_I_METHOD_1_WAY))
1215 giop_recv_list_setup_queue_entry_async (
1216 &aqe->mqe, (GIOPAsyncCallback) async_recv_cb);
1217 else if (fn)
1218 g_warning ("oneway method being invoked async with a callback");
1219
1220 if (!orbit_small_marshal (aqe->obj, cnx, &aqe->mqe, request_id,
1221 m_data, args, ctx))
1222 goto system_exception;
1223
1224 if (m_data->flags & ORBit_I_METHOD_1_WAY)
1225 giop_recv_list_destroy_queue_entry (&aqe->mqe);
1226
1227 aqe->completion_status = CORBA_COMPLETED_MAYBE;
1228 aqe->fn = fn;
1229 aqe->user_data = user_data;
1230 /* FIXME: perenial ORBit_IMethod lifecycle issues */
1231 aqe->m_data = /* ORBit_RootObject_duplicate */ (m_data);
1232
1233 clean_out:
1234 if (cnx)
1235 giop_connection_unref (cnx);
1236 tprintf_end_method ();
1237 return;
1238
1239 system_exception:
1240 tprintf ("[System exception comm failure] )");
1241 CORBA_exception_set_system (ev, ex_CORBA_COMM_FAILURE,
1242 aqe->completion_status);
1243 g_free (aqe);
1244 goto clean_out;
1245 }
1246
1247 gpointer
ORBit_small_get_servant(CORBA_Object obj)1248 ORBit_small_get_servant (CORBA_Object obj)
1249 {
1250 ORBit_POAObject pobj;
1251
1252 if (!obj || !obj->adaptor_obj || !obj->adaptor_obj->interface)
1253 return NULL;
1254
1255 if (obj->adaptor_obj->interface->adaptor_type != ORBIT_ADAPTOR_POA) {
1256 g_warning ("Not a poa object !");
1257 return NULL;
1258 }
1259
1260 pobj = (ORBit_POAObject)obj->adaptor_obj;
1261
1262 return pobj ? pobj->servant : NULL;
1263 }
1264
1265 static ORBitConnectionStatus
get_status(GIOPConnection * cnx)1266 get_status (GIOPConnection *cnx)
1267 {
1268 ORBitConnectionStatus ret;
1269
1270 g_return_val_if_fail (cnx != NULL, ORBIT_CONNECTION_DISCONNECTED);
1271
1272 switch (link_connection_get_status (LINK_CONNECTION (cnx))) {
1273 case LINK_CONNECTED:
1274 ret = ORBIT_CONNECTION_CONNECTED;
1275 break;
1276 case LINK_CONNECTING:
1277 ret = ORBIT_CONNECTION_CONNECTED;
1278 break;
1279 default:
1280 ret = ORBIT_CONNECTION_DISCONNECTED;
1281 break;
1282 }
1283 return ret;
1284 }
1285
1286 ORBitConnectionStatus
ORBit_small_get_connection_status(CORBA_Object obj)1287 ORBit_small_get_connection_status (CORBA_Object obj)
1288 {
1289 ORBitConnectionStatus ret;
1290
1291 g_return_val_if_fail (obj != CORBA_OBJECT_NIL,
1292 ORBIT_CONNECTION_DISCONNECTED);
1293
1294 if (ORBit_small_get_servant (obj))
1295 ret = ORBIT_CONNECTION_IN_PROC;
1296 else {
1297 GIOPConnection *cnx;
1298
1299 cnx = ORBit_object_get_connection (obj);
1300
1301 if (cnx) {
1302 ret = get_status (cnx);
1303 giop_connection_unref (cnx);
1304 } else
1305 ret = ORBIT_CONNECTION_DISCONNECTED;
1306 }
1307
1308 return ret;
1309 }
1310
1311 ORBitConnectionStatus
ORBit_small_listen_for_broken(CORBA_Object obj,GCallback fn,gpointer user_data)1312 ORBit_small_listen_for_broken (CORBA_Object obj,
1313 GCallback fn,
1314 gpointer user_data)
1315 {
1316 ORBitConnectionStatus ret;
1317
1318 if (!obj)
1319 ret = ORBIT_CONNECTION_DISCONNECTED;
1320
1321 else if (ORBit_small_get_servant (obj))
1322 ret = ORBIT_CONNECTION_IN_PROC;
1323
1324 else {
1325 GIOPConnection *cnx;
1326
1327 cnx = ORBit_object_get_connection (obj);
1328
1329 if (cnx) {
1330 ret = get_status (cnx);
1331 link_connection_add_broken_cb
1332 (LINK_CONNECTION (cnx),
1333 (LinkBrokenCallback)fn, user_data);
1334 giop_connection_unref (cnx);
1335 } else
1336 ret = ORBIT_CONNECTION_DISCONNECTED;
1337 }
1338
1339 return ret;
1340 }
1341
1342 ORBitConnectionStatus
ORBit_small_unlisten_for_broken_full(CORBA_Object obj,GCallback fn,gpointer user_data)1343 ORBit_small_unlisten_for_broken_full (CORBA_Object obj,
1344 GCallback fn,
1345 gpointer user_data)
1346 {
1347 ORBitConnectionStatus ret;
1348
1349 if (!obj)
1350 ret = ORBIT_CONNECTION_DISCONNECTED;
1351
1352 else if (ORBit_small_get_servant (obj))
1353 ret = ORBIT_CONNECTION_IN_PROC;
1354
1355 else {
1356 GIOPConnection *cnx;
1357
1358 cnx = ORBit_object_peek_connection (obj);
1359
1360 if (cnx) {
1361 ret = get_status (cnx);
1362 link_connection_remove_broken_cb
1363 (LINK_CONNECTION (cnx),
1364 (LinkBrokenCallback)fn, user_data);
1365 giop_connection_unref (cnx);
1366 } else
1367 ret = ORBIT_CONNECTION_DISCONNECTED;
1368 }
1369
1370 return ret;
1371 }
1372
1373 ORBitConnectionStatus
ORBit_small_unlisten_for_broken(CORBA_Object obj,GCallback fn)1374 ORBit_small_unlisten_for_broken (CORBA_Object obj,
1375 GCallback fn)
1376 {
1377 return ORBit_small_unlisten_for_broken_full (obj, fn, NULL);
1378 }
1379
1380 ORBitConnection *
ORBit_small_get_connection_ref(CORBA_Object obj)1381 ORBit_small_get_connection_ref (CORBA_Object obj)
1382 {
1383 return (ORBitConnection *) ORBit_object_get_connection (obj);
1384 }
1385
1386 ORBitConnection *
ORBit_small_get_connection(CORBA_Object obj)1387 ORBit_small_get_connection (CORBA_Object obj)
1388 {
1389 ORBitConnection *cnx;
1390
1391 cnx = ORBit_small_get_connection_ref (obj);
1392
1393 /* This sucks but compatibily */
1394 ORBit_small_connection_unref (cnx);
1395
1396 return cnx;
1397 }
1398
1399 void
ORBit_small_connection_unref(ORBitConnection * cnx)1400 ORBit_small_connection_unref (ORBitConnection *cnx)
1401 {
1402 if (cnx)
1403 giop_connection_unref (GIOP_CONNECTION (cnx));
1404 }
1405
1406 void
ORBit_connection_set_max_buffer(ORBitConnection * cnx,gulong max_buffer_bytes)1407 ORBit_connection_set_max_buffer (ORBitConnection *cnx,
1408 gulong max_buffer_bytes)
1409 {
1410 LinkConnection *lcnx = (LinkConnection *) cnx;
1411
1412 g_return_if_fail (LINK_IS_CONNECTION (lcnx));
1413
1414 link_connection_set_max_buffer (lcnx, max_buffer_bytes);
1415 }
1416