1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4
5 #include <IceUtil/DisableWarnings.h>
6 #include <Communicator.h>
7 #include <BatchRequestInterceptor.h>
8 #include <Dispatcher.h>
9 #include <ImplicitContext.h>
10 #include <Logger.h>
11 #include <ObjectAdapter.h>
12 #include <Operation.h>
13 #include <Properties.h>
14 #include <PropertiesAdmin.h>
15 #include <Proxy.h>
16 #include <Thread.h>
17 #include <Types.h>
18 #include <Util.h>
19 #include <ValueFactoryManager.h>
20 #include <Ice/ValueFactory.h>
21 #include <Ice/Initialize.h>
22 #include <Ice/CommunicatorAsync.h>
23 #include <Ice/LocalException.h>
24 #include <Ice/Locator.h>
25 #include <Ice/ObjectAdapter.h>
26 #include <Ice/Properties.h>
27 #include <Ice/Router.h>
28
29 #include <pythread.h>
30
31 using namespace std;
32 using namespace IcePy;
33
34 #if defined(__GNUC__) && ((__GNUC__ >= 8))
35 # pragma GCC diagnostic ignored "-Wcast-function-type"
36 #endif
37
38 #if PY_VERSION_HEX < 0x03070000
39 static long _mainThreadId;
40 #else
41 static unsigned long _mainThreadId;
42 #endif
43
44 typedef map<Ice::CommunicatorPtr, PyObject*> CommunicatorMap;
45 static CommunicatorMap _communicatorMap;
46
47 namespace IcePy
48 {
49
50 struct CommunicatorObject;
51
52 typedef InvokeThread<Ice::Communicator> WaitForShutdownThread;
53 typedef IceUtil::Handle<WaitForShutdownThread> WaitForShutdownThreadPtr;
54
55 struct CommunicatorObject
56 {
57 PyObject_HEAD
58 Ice::CommunicatorPtr* communicator;
59 PyObject* wrapper;
60 IceUtil::Monitor<IceUtil::Mutex>* shutdownMonitor;
61 WaitForShutdownThreadPtr* shutdownThread;
62 bool shutdown;
63 DispatcherPtr* dispatcher;
64 };
65
66 }
67
68 #ifdef WIN32
69 extern "C"
70 #endif
71 static CommunicatorObject*
communicatorNew(PyTypeObject * type,PyObject *,PyObject *)72 communicatorNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/)
73 {
74 assert(type && type->tp_alloc);
75 CommunicatorObject* self = reinterpret_cast<CommunicatorObject*>(type->tp_alloc(type, 0));
76 if(!self)
77 {
78 return 0;
79 }
80 self->communicator = 0;
81 self->wrapper = 0;
82 self->shutdownMonitor = new IceUtil::Monitor<IceUtil::Mutex>;
83 self->shutdownThread = 0;
84 self->shutdown = false;
85 self->dispatcher = 0;
86 return self;
87 }
88
89 #ifdef WIN32
90 extern "C"
91 #endif
92 static int
communicatorInit(CommunicatorObject * self,PyObject * args,PyObject *)93 communicatorInit(CommunicatorObject* self, PyObject* args, PyObject* /*kwds*/)
94 {
95 //
96 // The argument options are:
97 //
98 // Ice.initialize()
99 // Ice.initialize(args)
100 // Ice.initialize(initData)
101 // Ice.initialize(configFile)
102 // Ice.initialize(args, initData)
103 // Ice.initialize(args, configFile)
104 //
105
106 PyObject* arg1 = 0;
107 PyObject* arg2 = 0;
108 if(!PyArg_ParseTuple(args, STRCAST("|OO"), &arg1, &arg2))
109 {
110 return -1;
111 }
112
113 PyObject* argList = 0;
114 PyObject* initData = 0;
115 PyObject* configFile = 0;
116
117 if(arg1 == Py_None)
118 {
119 arg1 = 0;
120 }
121
122 if(arg2 == Py_None)
123 {
124 arg2 = 0;
125 }
126
127 PyObject* initDataType = lookupType("Ice.InitializationData");
128
129 if(arg1)
130 {
131 if(PyList_Check(arg1))
132 {
133 argList = arg1;
134 }
135 else if(PyObject_IsInstance(arg1, initDataType))
136 {
137 initData = arg1;
138 }
139 else if(checkString(arg1))
140 {
141 configFile = arg1;
142 }
143 else
144 {
145 PyErr_Format(PyExc_ValueError,
146 STRCAST("initialize expects an argument list, Ice.InitializationData or a configuration filename"));
147 return -1;
148 }
149 }
150
151 if(arg2)
152 {
153 if(PyList_Check(arg2))
154 {
155 if(argList)
156 {
157 PyErr_Format(PyExc_ValueError, STRCAST("unexpected list argument to initialize"));
158 return -1;
159 }
160 argList = arg2;
161 }
162 else if(PyObject_IsInstance(arg2, initDataType))
163 {
164 if(initData)
165 {
166 PyErr_Format(PyExc_ValueError, STRCAST("unexpected Ice.InitializationData argument to initialize"));
167 return -1;
168 }
169 initData = arg2;
170 }
171 else if(checkString(arg2))
172 {
173 if(configFile)
174 {
175 PyErr_Format(PyExc_ValueError, STRCAST("unexpected string argument to initialize"));
176 return -1;
177 }
178 configFile = arg2;
179 }
180 else
181 {
182 PyErr_Format(PyExc_ValueError,
183 STRCAST("initialize expects an argument list, Ice.InitializationData or a configuration filename"));
184 return -1;
185 }
186 }
187
188 if(initData && configFile)
189 {
190 PyErr_Format(PyExc_ValueError,
191 STRCAST("initialize accepts either Ice.InitializationData or a configuration filename"));
192 return -1;
193 }
194
195 Ice::StringSeq seq;
196 if(argList && !listToStringSeq(argList, seq))
197 {
198 return -1;
199 }
200
201 Ice::InitializationData data;
202 DispatcherPtr dispatcherWrapper;
203
204 try
205 {
206 if(initData)
207 {
208 PyObjectHandle properties = getAttr(initData, "properties", false);
209 PyObjectHandle logger = getAttr(initData, "logger", false);
210 PyObjectHandle threadHook = getAttr(initData, "threadHook", false);
211 PyObjectHandle threadStart = getAttr(initData, "threadStart", false);
212 PyObjectHandle threadStop = getAttr(initData, "threadStop", false);
213 PyObjectHandle batchRequestInterceptor = getAttr(initData, "batchRequestInterceptor", false);
214 PyObjectHandle dispatcher = getAttr(initData, "dispatcher", false);
215
216 if(properties.get())
217 {
218 //
219 // Get the properties implementation.
220 //
221 PyObjectHandle impl = getAttr(properties.get(), "_impl", false);
222 assert(impl.get());
223 data.properties = getProperties(impl.get());
224 }
225
226 if(logger.get())
227 {
228 data.logger = new LoggerWrapper(logger.get());
229 }
230
231 if(threadHook.get() || threadStart.get() || threadStop.get())
232 {
233 data.threadHook = new ThreadHook(threadHook.get(), threadStart.get(), threadStop.get());
234 }
235
236 if(dispatcher.get())
237 {
238 dispatcherWrapper = new Dispatcher(dispatcher.get());
239 data.dispatcher = dispatcherWrapper;
240 }
241
242 if(batchRequestInterceptor.get())
243 {
244 data.batchRequestInterceptor = new BatchRequestInterceptor(batchRequestInterceptor.get());
245 }
246 }
247
248 //
249 // We always supply our own implementation of ValueFactoryManager.
250 //
251 data.valueFactoryManager = new ValueFactoryManager;
252
253 if(!data.properties)
254 {
255 data.properties = Ice::createProperties();
256 }
257
258 if(configFile)
259 {
260 data.properties->load(getString(configFile));
261 }
262
263 if(argList)
264 {
265 data.properties = Ice::createProperties(seq, data.properties);
266 }
267 }
268 catch(const Ice::Exception& ex)
269 {
270 setPythonException(ex);
271 return -1;
272 }
273
274 //
275 // Remaining command line options are passed to the communicator
276 // as an argument vector in case they contain plug-in properties.
277 //
278 int argc = static_cast<int>(seq.size());
279 char** argv = new char*[argc + 1];
280 int i = 0;
281 for(Ice::StringSeq::const_iterator s = seq.begin(); s != seq.end(); ++s, ++i)
282 {
283 argv[i] = strdup(s->c_str());
284 }
285 argv[argc] = 0;
286
287 data.compactIdResolver = new IdResolver;
288
289 Ice::CommunicatorPtr communicator;
290 try
291 {
292 AllowThreads allowThreads;
293 if(argList)
294 {
295 communicator = Ice::initialize(argc, argv, data);
296 }
297 else
298 {
299 communicator = Ice::initialize(data);
300 }
301 }
302 catch(const Ice::Exception& ex)
303 {
304 for(i = 0; i < argc; ++i)
305 {
306 free(argv[i]);
307 }
308 delete[] argv;
309
310 setPythonException(ex);
311 return -1;
312 }
313
314 //
315 // Replace the contents of the given argument list with the filtered arguments.
316 //
317 if(argList)
318 {
319 PyList_SetSlice(argList, 0, PyList_Size(argList), 0); // Clear the list.
320
321 for(i = 0; i < argc; ++i)
322 {
323 PyObjectHandle str = Py_BuildValue(STRCAST("s"), argv[i]);
324 PyList_Append(argList, str.get());
325 }
326 }
327
328 for(i = 0; i < argc; ++i)
329 {
330 free(argv[i]);
331 }
332 delete[] argv;
333
334 self->communicator = new Ice::CommunicatorPtr(communicator);
335
336 CommunicatorMap::iterator p = _communicatorMap.find(communicator);
337 if(p != _communicatorMap.end())
338 {
339 _communicatorMap.erase(p);
340 }
341 _communicatorMap.insert(CommunicatorMap::value_type(communicator, reinterpret_cast<PyObject*>(self)));
342
343 if(dispatcherWrapper)
344 {
345 self->dispatcher = new DispatcherPtr(dispatcherWrapper);
346 dispatcherWrapper->setCommunicator(communicator);
347 }
348
349 return 0;
350 }
351
352 #ifdef WIN32
353 extern "C"
354 #endif
355 static void
communicatorDealloc(CommunicatorObject * self)356 communicatorDealloc(CommunicatorObject* self)
357 {
358 if(self->communicator)
359 {
360 CommunicatorMap::iterator p = _communicatorMap.find(*self->communicator);
361 //
362 // find() can fail if an error occurred during communicator initialization.
363 //
364 if(p != _communicatorMap.end())
365 {
366 _communicatorMap.erase(p);
367 }
368 }
369
370 if(self->shutdownThread)
371 {
372 (*self->shutdownThread)->getThreadControl().join();
373 }
374 delete self->communicator;
375 delete self->shutdownMonitor;
376 delete self->shutdownThread;
377 Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
378 }
379
380 #ifdef WIN32
381 extern "C"
382 #endif
383 static PyObject*
communicatorDestroy(CommunicatorObject * self,PyObject *)384 communicatorDestroy(CommunicatorObject* self, PyObject* /*args*/)
385 {
386 assert(self->communicator);
387
388 ValueFactoryManagerPtr vfm = ValueFactoryManagerPtr::dynamicCast((*self->communicator)->getValueFactoryManager());
389 assert(vfm);
390
391 try
392 {
393 AllowThreads allowThreads; // Release Python's global interpreter lock to avoid a potential deadlock.
394 (*self->communicator)->destroy();
395 }
396 catch(const Ice::Exception& ex)
397 {
398 setPythonException(ex);
399 }
400
401 vfm->destroy();
402
403 if(self->dispatcher)
404 {
405 (*self->dispatcher)->setCommunicator(0); // Break cyclic reference.
406 }
407
408 //
409 // Break cyclic reference between this object and its Python wrapper.
410 //
411 Py_XDECREF(self->wrapper);
412 self->wrapper = 0;
413
414 if(PyErr_Occurred())
415 {
416 return 0;
417 }
418 else
419 {
420 Py_INCREF(Py_None);
421 return Py_None;
422 }
423 }
424
425 #ifdef WIN32
426 extern "C"
427 #endif
428 static PyObject*
communicatorShutdown(CommunicatorObject * self,PyObject *)429 communicatorShutdown(CommunicatorObject* self, PyObject* /*args*/)
430 {
431 assert(self->communicator);
432 try
433 {
434 AllowThreads allowThreads; // Release Python's global interpreter lock to avoid a potential deadlock.
435 (*self->communicator)->shutdown();
436 }
437 catch(const Ice::Exception& ex)
438 {
439 setPythonException(ex);
440 return 0;
441 }
442
443 Py_INCREF(Py_None);
444 return Py_None;
445 }
446
447 #ifdef WIN32
448 extern "C"
449 #endif
450 static PyObject*
communicatorWaitForShutdown(CommunicatorObject * self,PyObject * args)451 communicatorWaitForShutdown(CommunicatorObject* self, PyObject* args)
452 {
453 //
454 // This method differs somewhat from the standard Ice API because of
455 // signal issues. This method expects an integer timeout value, and
456 // returns a boolean to indicate whether it was successful. When
457 // called from the main thread, the timeout is used to allow control
458 // to return to the caller (the Python interpreter) periodically.
459 // When called from any other thread, we call waitForShutdown directly
460 // and ignore the timeout.
461 //
462 int timeout = 0;
463 if(!PyArg_ParseTuple(args, STRCAST("i"), &timeout))
464 {
465 return 0;
466 }
467
468 assert(timeout > 0);
469 assert(self->communicator);
470
471 //
472 // Do not call waitForShutdown from the main thread, because it prevents
473 // signals (such as keyboard interrupts) from being delivered to Python.
474 //
475 if(PyThread_get_thread_ident() == _mainThreadId)
476 {
477 IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*self->shutdownMonitor);
478
479 if(!self->shutdown)
480 {
481 if(self->shutdownThread == 0)
482 {
483 WaitForShutdownThreadPtr t = new WaitForShutdownThread(*self->communicator,
484 &Ice::Communicator::waitForShutdown,
485 *self->shutdownMonitor, self->shutdown);
486 self->shutdownThread = new WaitForShutdownThreadPtr(t);
487 t->start();
488 }
489
490 while(!self->shutdown)
491 {
492 bool done;
493 {
494 AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls.
495 done = (*self->shutdownMonitor).timedWait(IceUtil::Time::milliSeconds(timeout));
496 }
497
498 if(!done)
499 {
500 PyRETURN_FALSE;
501 }
502 }
503 }
504
505 assert(self->shutdown);
506
507 Ice::Exception* ex = (*self->shutdownThread)->getException();
508 if(ex)
509 {
510 setPythonException(*ex);
511 return 0;
512 }
513 }
514 else
515 {
516 try
517 {
518 AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls.
519 (*self->communicator)->waitForShutdown();
520 }
521 catch(const Ice::Exception& ex)
522 {
523 setPythonException(ex);
524 return 0;
525 }
526 }
527
528 PyRETURN_TRUE;
529 }
530
531 #ifdef WIN32
532 extern "C"
533 #endif
534 static PyObject*
communicatorIsShutdown(CommunicatorObject * self,PyObject *)535 communicatorIsShutdown(CommunicatorObject* self, PyObject* /*args*/)
536 {
537 assert(self->communicator);
538 bool isShutdown;
539 try
540 {
541 isShutdown = (*self->communicator)->isShutdown();
542 }
543 catch(const Ice::Exception& ex)
544 {
545 setPythonException(ex);
546 return 0;
547 }
548
549 PyRETURN_BOOL(isShutdown);
550 }
551
552 #ifdef WIN32
553 extern "C"
554 #endif
555 static PyObject*
communicatorStringToProxy(CommunicatorObject * self,PyObject * args)556 communicatorStringToProxy(CommunicatorObject* self, PyObject* args)
557 {
558 PyObject* strObj;
559 if(!PyArg_ParseTuple(args, STRCAST("O"), &strObj))
560 {
561 return 0;
562 }
563
564 string str;
565 if(!getStringArg(strObj, "str", str))
566 {
567 return 0;
568 }
569
570 assert(self->communicator);
571 Ice::ObjectPrx proxy;
572 try
573 {
574 proxy = (*self->communicator)->stringToProxy(str);
575 if(proxy)
576 {
577 return createProxy(proxy, *self->communicator);
578 }
579 }
580 catch(const Ice::Exception& ex)
581 {
582 setPythonException(ex);
583 return 0;
584 }
585
586 Py_INCREF(Py_None);
587 return Py_None;
588 }
589
590 #ifdef WIN32
591 extern "C"
592 #endif
593 static PyObject*
communicatorProxyToString(CommunicatorObject * self,PyObject * args)594 communicatorProxyToString(CommunicatorObject* self, PyObject* args)
595 {
596 PyObject* obj;
597 if(!PyArg_ParseTuple(args, STRCAST("O"), &obj))
598 {
599 return 0;
600 }
601
602 Ice::ObjectPrx proxy;
603 if(!getProxyArg(obj, "proxyToString", "obj", proxy))
604 {
605 return 0;
606 }
607
608 string str;
609
610 assert(self->communicator);
611 try
612 {
613 str = (*self->communicator)->proxyToString(proxy);
614 }
615 catch(const Ice::Exception& ex)
616 {
617 setPythonException(ex);
618 return 0;
619 }
620
621 return createString(str);
622 }
623
624 #ifdef WIN32
625 extern "C"
626 #endif
627 static PyObject*
communicatorPropertyToProxy(CommunicatorObject * self,PyObject * args)628 communicatorPropertyToProxy(CommunicatorObject* self, PyObject* args)
629 {
630 PyObject* strObj;
631 if(!PyArg_ParseTuple(args, STRCAST("O"), &strObj))
632 {
633 return 0;
634 }
635
636 string str;
637 if(!getStringArg(strObj, "property", str))
638 {
639 return 0;
640 }
641
642 assert(self->communicator);
643 Ice::ObjectPrx proxy;
644 try
645 {
646 proxy = (*self->communicator)->propertyToProxy(str);
647 if(proxy)
648 {
649 return createProxy(proxy, *self->communicator);
650 }
651 }
652 catch(const Ice::Exception& ex)
653 {
654 setPythonException(ex);
655 return 0;
656 }
657
658 Py_INCREF(Py_None);
659 return Py_None;
660 }
661
662 #ifdef WIN32
663 extern "C"
664 #endif
665 static PyObject*
communicatorProxyToProperty(CommunicatorObject * self,PyObject * args)666 communicatorProxyToProperty(CommunicatorObject* self, PyObject* args)
667 {
668 //
669 // We don't want to accept None here, so we can specify ProxyType and force
670 // the caller to supply a proxy object.
671 //
672 PyObject* proxyObj;
673 PyObject* strObj;
674 if(!PyArg_ParseTuple(args, STRCAST("O!O"), &ProxyType, &proxyObj, &strObj))
675 {
676 return 0;
677 }
678
679 Ice::ObjectPrx proxy = getProxy(proxyObj);
680 string str;
681 if(!getStringArg(strObj, "property", str))
682 {
683 return 0;
684 }
685
686 assert(self->communicator);
687 Ice::PropertyDict dict;
688 try
689 {
690 dict = (*self->communicator)->proxyToProperty(proxy, str);
691 }
692 catch(const Ice::Exception& ex)
693 {
694 setPythonException(ex);
695 return 0;
696 }
697
698 PyObjectHandle result = PyDict_New();
699 if(result.get())
700 {
701 for(Ice::PropertyDict::iterator p = dict.begin(); p != dict.end(); ++p)
702 {
703 PyObjectHandle key = createString(p->first);
704 PyObjectHandle val = createString(p->second);
705 if(!val.get() || PyDict_SetItem(result.get(), key.get(), val.get()) < 0)
706 {
707 return 0;
708 }
709 }
710 }
711
712 return result.release();
713 }
714
715 #ifdef WIN32
716 extern "C"
717 #endif
718 static PyObject*
communicatorStringToIdentity(CommunicatorObject * self,PyObject * args)719 communicatorStringToIdentity(CommunicatorObject* self, PyObject* args)
720 {
721 PyObject* strObj;
722 if(!PyArg_ParseTuple(args, STRCAST("O"), &strObj))
723 {
724 return 0;
725 }
726
727 string str;
728 if(!getStringArg(strObj, "str", str))
729 {
730 return 0;
731 }
732
733 assert(self->communicator);
734 Ice::Identity id;
735 try
736 {
737 id = (*self->communicator)->stringToIdentity(str);
738 }
739 catch(const Ice::Exception& ex)
740 {
741 setPythonException(ex);
742 return 0;
743 }
744
745 return createIdentity(id);
746 }
747
748 #ifdef WIN32
749 extern "C"
750 #endif
751 static PyObject*
communicatorIdentityToString(CommunicatorObject * self,PyObject * args)752 communicatorIdentityToString(CommunicatorObject* self, PyObject* args)
753 {
754 PyObject* identityType = lookupType("Ice.Identity");
755 PyObject* obj;
756 if(!PyArg_ParseTuple(args, STRCAST("O!"), identityType, &obj))
757 {
758 return 0;
759 }
760
761 Ice::Identity id;
762 if(!getIdentity(obj, id))
763 {
764 return 0;
765 }
766 string str;
767
768 assert(self->communicator);
769 try
770 {
771 str = (*self->communicator)->identityToString(id);
772 }
773 catch(const Ice::Exception& ex)
774 {
775 setPythonException(ex);
776 return 0;
777 }
778
779 return createString(str);
780 }
781
782 #ifdef WIN32
783 extern "C"
784 #endif
785 static PyObject*
communicatorFlushBatchRequests(CommunicatorObject * self,PyObject * args)786 communicatorFlushBatchRequests(CommunicatorObject* self, PyObject* args)
787 {
788 PyObject* compressBatchType = lookupType("Ice.CompressBatch");
789 PyObject* compressBatch;
790 if(!PyArg_ParseTuple(args, STRCAST("O!"), compressBatchType, &compressBatch))
791 {
792 return 0;
793 }
794
795 PyObjectHandle v = getAttr(compressBatch, "_value", false);
796 assert(v.get());
797 Ice::CompressBatch cb = static_cast<Ice::CompressBatch>(PyLong_AsLong(v.get()));
798
799 assert(self->communicator);
800 try
801 {
802 AllowThreads allowThreads; // Release Python's global interpreter lock to avoid a potential deadlock.
803 (*self->communicator)->flushBatchRequests(cb);
804 }
805 catch(const Ice::Exception& ex)
806 {
807 setPythonException(ex);
808 return 0;
809 }
810
811 Py_INCREF(Py_None);
812 return Py_None;
813 }
814
815 #ifdef WIN32
816 extern "C"
817 #endif
818 static PyObject*
communicatorFlushBatchRequestsAsync(CommunicatorObject * self,PyObject * args,PyObject *)819 communicatorFlushBatchRequestsAsync(CommunicatorObject* self, PyObject* args, PyObject* /*kwds*/)
820 {
821 PyObject* compressBatchType = lookupType("Ice.CompressBatch");
822 PyObject* compressBatch;
823 if(!PyArg_ParseTuple(args, STRCAST("O!"), compressBatchType, &compressBatch))
824 {
825 return 0;
826 }
827
828 PyObjectHandle v = getAttr(compressBatch, "_value", false);
829 assert(v.get());
830 Ice::CompressBatch cb = static_cast<Ice::CompressBatch>(PyLong_AsLong(v.get()));
831
832 assert(self->communicator);
833 const string op = "flushBatchRequests";
834
835 FlushAsyncCallbackPtr d = new FlushAsyncCallback(op);
836 Ice::Callback_Communicator_flushBatchRequestsPtr callback =
837 Ice::newCallback_Communicator_flushBatchRequests(d, &FlushAsyncCallback::exception, &FlushAsyncCallback::sent);
838
839 Ice::AsyncResultPtr result;
840
841 try
842 {
843 result = (*self->communicator)->begin_flushBatchRequests(cb, callback);
844 }
845 catch(const Ice::Exception& ex)
846 {
847 setPythonException(ex);
848 return 0;
849 }
850
851 PyObjectHandle asyncResultObj = createAsyncResult(result, 0, 0, self->wrapper);
852 if(!asyncResultObj.get())
853 {
854 return 0;
855 }
856
857 PyObjectHandle future = createFuture(op, asyncResultObj.get());
858 if(!future.get())
859 {
860 return 0;
861 }
862 d->setFuture(future.get());
863 return future.release();
864 }
865
866 #ifdef WIN32
867 extern "C"
868 #endif
869 static PyObject*
communicatorBeginFlushBatchRequests(CommunicatorObject * self,PyObject * args,PyObject * kwds)870 communicatorBeginFlushBatchRequests(CommunicatorObject* self, PyObject* args, PyObject* kwds)
871 {
872 assert(self->communicator);
873
874 static char* argNames[] =
875 {
876 const_cast<char*>("compress"),
877 const_cast<char*>("_ex"),
878 const_cast<char*>("_sent"),
879 0
880 };
881 PyObject* compressBatch;
882 PyObject* ex = Py_None;
883 PyObject* sent = Py_None;
884 if(!PyArg_ParseTupleAndKeywords(args, kwds, STRCAST("O|OO"), argNames, &compressBatch, &ex, &sent))
885 {
886 return 0;
887 }
888
889 PyObject* compressBatchType = lookupType("Ice.CompressBatch");
890 if(!PyObject_IsInstance(compressBatch, reinterpret_cast<PyObject*>(compressBatchType)))
891 {
892 PyErr_Format(PyExc_ValueError, STRCAST("expected an Ice.CompressBatch enumerator"));
893 return 0;
894 }
895
896 PyObjectHandle v = getAttr(compressBatch, "_value", false);
897 assert(v.get());
898 Ice::CompressBatch cb = static_cast<Ice::CompressBatch>(PyLong_AsLong(v.get()));
899
900 if(ex == Py_None)
901 {
902 ex = 0;
903 }
904 if(sent == Py_None)
905 {
906 sent = 0;
907 }
908
909 if(!ex && sent)
910 {
911 PyErr_Format(PyExc_RuntimeError,
912 STRCAST("exception callback must also be provided when sent callback is used"));
913 return 0;
914 }
915
916 Ice::Callback_Communicator_flushBatchRequestsPtr callback;
917 if(ex || sent)
918 {
919 FlushCallbackPtr d = new FlushCallback(ex, sent, "flushBatchRequests");
920 callback = Ice::newCallback_Communicator_flushBatchRequests(d, &FlushCallback::exception, &FlushCallback::sent);
921 }
922
923 Ice::AsyncResultPtr result;
924 try
925 {
926 if(callback)
927 {
928 result = (*self->communicator)->begin_flushBatchRequests(cb, callback);
929 }
930 else
931 {
932 result = (*self->communicator)->begin_flushBatchRequests(cb);
933 }
934 }
935 catch(const Ice::Exception& e)
936 {
937 setPythonException(e);
938 return 0;
939 }
940
941 return createAsyncResult(result, 0, 0, self->wrapper);
942 }
943
944 #ifdef WIN32
945 extern "C"
946 #endif
947 static PyObject*
communicatorEndFlushBatchRequests(CommunicatorObject * self,PyObject * args)948 communicatorEndFlushBatchRequests(CommunicatorObject* self, PyObject* args)
949 {
950 assert(self->communicator);
951
952 PyObject* result;
953 if(!PyArg_ParseTuple(args, STRCAST("O!"), &AsyncResultType, &result))
954 {
955 return 0;
956 }
957
958 Ice::AsyncResultPtr r = getAsyncResult(result);
959 try
960 {
961 AllowThreads allowThreads; // Release Python's global interpreter lock during blocking invocations.
962 (*self->communicator)->end_flushBatchRequests(r);
963 }
964 catch(const Ice::Exception& ex)
965 {
966 setPythonException(ex);
967 return 0;
968 }
969
970 Py_INCREF(Py_None);
971 return Py_None;
972 }
973
974 #ifdef WIN32
975 extern "C"
976 #endif
977 static PyObject*
communicatorCreateAdmin(CommunicatorObject * self,PyObject * args)978 communicatorCreateAdmin(CommunicatorObject* self, PyObject* args)
979 {
980 PyObject* adapter;
981 PyObject* identityType = lookupType("Ice.Identity");
982 PyObject* id;
983 if(!PyArg_ParseTuple(args, STRCAST("OO!"), &adapter, identityType, &id))
984 {
985 return 0;
986 }
987
988 Ice::ObjectAdapterPtr oa;
989
990 PyObject* adapterType = lookupType("Ice.ObjectAdapter");
991 if(adapter != Py_None && !PyObject_IsInstance(adapter, adapterType))
992 {
993 PyErr_Format(PyExc_ValueError, STRCAST("expected ObjectAdapter or None"));
994 return 0;
995 }
996
997 if(adapter != Py_None)
998 {
999 oa = unwrapObjectAdapter(adapter);
1000 }
1001
1002 Ice::Identity identity;
1003 if(!getIdentity(id, identity))
1004 {
1005 return 0;
1006 }
1007
1008 assert(self->communicator);
1009 Ice::ObjectPrx proxy;
1010 try
1011 {
1012 proxy = (*self->communicator)->createAdmin(oa, identity);
1013 assert(proxy);
1014
1015 return createProxy(proxy, *self->communicator);
1016 }
1017 catch(const Ice::Exception& ex)
1018 {
1019 setPythonException(ex);
1020 return 0;
1021 }
1022 }
1023
1024 #ifdef WIN32
1025 extern "C"
1026 #endif
1027 static PyObject*
communicatorGetAdmin(CommunicatorObject * self,PyObject *)1028 communicatorGetAdmin(CommunicatorObject* self, PyObject* /*args*/)
1029 {
1030 assert(self->communicator);
1031 Ice::ObjectPrx proxy;
1032 try
1033 {
1034 proxy = (*self->communicator)->getAdmin();
1035 if(proxy)
1036 {
1037 return createProxy(proxy, *self->communicator);
1038 }
1039 }
1040 catch(const Ice::Exception& ex)
1041 {
1042 setPythonException(ex);
1043 return 0;
1044 }
1045
1046 Py_INCREF(Py_None);
1047 return Py_None;
1048 }
1049
1050 #ifdef WIN32
1051 extern "C"
1052 #endif
1053 static PyObject*
communicatorAddAdminFacet(CommunicatorObject * self,PyObject * args)1054 communicatorAddAdminFacet(CommunicatorObject* self, PyObject* args)
1055 {
1056 PyObject* objectType = lookupType("Ice.Object");
1057 PyObject* servant;
1058 PyObject* facetObj;
1059 if(!PyArg_ParseTuple(args, STRCAST("O!O"), objectType, &servant, &facetObj))
1060 {
1061 return 0;
1062 }
1063
1064 string facet;
1065 if(!getStringArg(facetObj, "facet", facet))
1066 {
1067 return 0;
1068 }
1069
1070 ServantWrapperPtr wrapper = createServantWrapper(servant);
1071 if(PyErr_Occurred())
1072 {
1073 return 0;
1074 }
1075
1076 assert(self->communicator);
1077 try
1078 {
1079 (*self->communicator)->addAdminFacet(wrapper, facet);
1080 }
1081 catch(const Ice::Exception& ex)
1082 {
1083 setPythonException(ex);
1084 return 0;
1085 }
1086
1087 Py_INCREF(Py_None);
1088 return Py_None;
1089 }
1090
1091 #ifdef WIN32
1092 extern "C"
1093 #endif
1094 static PyObject*
communicatorFindAdminFacet(CommunicatorObject * self,PyObject * args)1095 communicatorFindAdminFacet(CommunicatorObject* self, PyObject* args)
1096 {
1097 PyObject* facetObj;
1098 if(!PyArg_ParseTuple(args, STRCAST("O"), &facetObj))
1099 {
1100 return 0;
1101 }
1102
1103 string facet;
1104 if(!getStringArg(facetObj, "facet", facet))
1105 {
1106 return 0;
1107 }
1108
1109 assert(self->communicator);
1110 try
1111 {
1112 //
1113 // The facet being found may not be implemented by a Python servant
1114 // (e.g., it could be the Process or Properties facet), in which case
1115 // we return None.
1116 //
1117 Ice::ObjectPtr obj = (*self->communicator)->findAdminFacet(facet);
1118 if(obj)
1119 {
1120 ServantWrapperPtr wrapper = ServantWrapperPtr::dynamicCast(obj);
1121 if(wrapper)
1122 {
1123 return wrapper->getObject();
1124 }
1125
1126 Ice::NativePropertiesAdminPtr props = Ice::NativePropertiesAdminPtr::dynamicCast(obj);
1127 if(props)
1128 {
1129 return createNativePropertiesAdmin(props);
1130 }
1131
1132 // If the facet isn't supported in Python, just return an Ice.Object.
1133 PyTypeObject* objectType = reinterpret_cast<PyTypeObject*>(lookupType("Ice.Object"));
1134 return objectType->tp_alloc(objectType, 0);
1135 }
1136 }
1137 catch(const Ice::Exception& ex)
1138 {
1139 setPythonException(ex);
1140 return 0;
1141 }
1142
1143 Py_INCREF(Py_None);
1144 return Py_None;
1145 }
1146
1147 #ifdef WIN32
1148 extern "C"
1149 #endif
1150 static PyObject*
communicatorFindAllAdminFacets(CommunicatorObject * self,PyObject *)1151 communicatorFindAllAdminFacets(CommunicatorObject* self, PyObject* /*args*/)
1152 {
1153 assert(self->communicator);
1154 Ice::FacetMap facetMap;
1155 try
1156 {
1157 facetMap = (*self->communicator)->findAllAdminFacets();
1158 }
1159 catch(const Ice::Exception& ex)
1160 {
1161 setPythonException(ex);
1162 return 0;
1163 }
1164
1165 PyObjectHandle result = PyDict_New();
1166 if(!result.get())
1167 {
1168 return 0;
1169 }
1170
1171 PyTypeObject* objectType = reinterpret_cast<PyTypeObject*>(lookupType("Ice.Object"));
1172 PyObjectHandle plainObject = objectType->tp_alloc(objectType, 0);
1173
1174 for(Ice::FacetMap::const_iterator p = facetMap.begin(); p != facetMap.end(); ++p)
1175 {
1176
1177 PyObjectHandle obj = plainObject;
1178
1179 ServantWrapperPtr wrapper = ServantWrapperPtr::dynamicCast(p->second);
1180 if(wrapper)
1181 {
1182 obj = wrapper->getObject();
1183 }
1184 else
1185 {
1186 Ice::NativePropertiesAdminPtr props = Ice::NativePropertiesAdminPtr::dynamicCast(p->second);
1187 if(props)
1188 {
1189 obj = createNativePropertiesAdmin(props);
1190 }
1191 }
1192
1193 if(PyDict_SetItemString(result.get(), const_cast<char*>(p->first.c_str()), obj.get()) < 0)
1194 {
1195 return 0;
1196 }
1197 }
1198
1199 return result.release();
1200 }
1201
1202 #ifdef WIN32
1203 extern "C"
1204 #endif
1205 static PyObject*
communicatorRemoveAdminFacet(CommunicatorObject * self,PyObject * args)1206 communicatorRemoveAdminFacet(CommunicatorObject* self, PyObject* args)
1207 {
1208 PyObject* facetObj;
1209 if(!PyArg_ParseTuple(args, STRCAST("O"), &facetObj))
1210 {
1211 return 0;
1212 }
1213
1214 string facet;
1215 if(!getStringArg(facetObj, "facet", facet))
1216 {
1217 return 0;
1218 }
1219
1220 assert(self->communicator);
1221 try
1222 {
1223 //
1224 // The facet being removed may not be implemented by a Python servant
1225 // (e.g., it could be the Process or Properties facet), in which case
1226 // we return None.
1227 //
1228 Ice::ObjectPtr obj = (*self->communicator)->removeAdminFacet(facet);
1229 assert(obj);
1230 ServantWrapperPtr wrapper = ServantWrapperPtr::dynamicCast(obj);
1231 if(wrapper)
1232 {
1233 return wrapper->getObject();
1234 }
1235 }
1236 catch(const Ice::Exception& ex)
1237 {
1238 setPythonException(ex);
1239 return 0;
1240 }
1241
1242 Py_INCREF(Py_None);
1243 return Py_None;
1244 }
1245
1246 #ifdef WIN32
1247 extern "C"
1248 #endif
1249 static PyObject*
communicatorSetWrapper(CommunicatorObject * self,PyObject * args)1250 communicatorSetWrapper(CommunicatorObject* self, PyObject* args)
1251 {
1252 PyObject* wrapper;
1253 if(!PyArg_ParseTuple(args, STRCAST("O"), &wrapper))
1254 {
1255 return 0;
1256 }
1257
1258 assert(!self->wrapper);
1259 self->wrapper = wrapper;
1260 Py_INCREF(self->wrapper);
1261
1262 Py_INCREF(Py_None);
1263 return Py_None;
1264 }
1265
1266 #ifdef WIN32
1267 extern "C"
1268 #endif
1269 static PyObject*
communicatorGetWrapper(CommunicatorObject * self,PyObject *)1270 communicatorGetWrapper(CommunicatorObject* self, PyObject* /*args*/)
1271 {
1272 assert(self->wrapper);
1273 Py_INCREF(self->wrapper);
1274 return self->wrapper;
1275 }
1276
1277 #ifdef WIN32
1278 extern "C"
1279 #endif
1280 static PyObject*
communicatorGetProperties(CommunicatorObject * self,PyObject *)1281 communicatorGetProperties(CommunicatorObject* self, PyObject* /*args*/)
1282 {
1283 assert(self->communicator);
1284 Ice::PropertiesPtr properties;
1285 try
1286 {
1287 properties = (*self->communicator)->getProperties();
1288 }
1289 catch(const Ice::Exception& ex)
1290 {
1291 setPythonException(ex);
1292 return 0;
1293 }
1294
1295 return createProperties(properties);
1296 }
1297
1298 #ifdef WIN32
1299 extern "C"
1300 #endif
1301 static PyObject*
communicatorGetLogger(CommunicatorObject * self,PyObject *)1302 communicatorGetLogger(CommunicatorObject* self, PyObject* /*args*/)
1303 {
1304 assert(self->communicator);
1305 Ice::LoggerPtr logger;
1306 try
1307 {
1308 logger = (*self->communicator)->getLogger();
1309 }
1310 catch(const Ice::Exception& ex)
1311 {
1312 setPythonException(ex);
1313 return 0;
1314 }
1315
1316 //
1317 // The communicator's logger can either be a C++ object (such as
1318 // the default logger supplied by the Ice run time), or a C++
1319 // wrapper around a Python implementation. If the latter, we
1320 // return it directly. Otherwise, we create a Python object
1321 // that delegates to the C++ object.
1322 //
1323 LoggerWrapperPtr wrapper = LoggerWrapperPtr::dynamicCast(logger);
1324 if(wrapper)
1325 {
1326 PyObject* obj = wrapper->getObject();
1327 Py_INCREF(obj);
1328 return obj;
1329 }
1330
1331 return createLogger(logger);
1332 }
1333
1334 #ifdef WIN32
1335 extern "C"
1336 #endif
1337 static PyObject*
communicatorAddObjectFactory(CommunicatorObject * self,PyObject * args)1338 communicatorAddObjectFactory(CommunicatorObject* self, PyObject* args)
1339 {
1340 PyObject* objectFactoryType = lookupType("Ice.ObjectFactory");
1341 assert(objectFactoryType);
1342 PyObject* valueFactoryType = lookupType("types.FunctionType");
1343 assert(valueFactoryType);
1344
1345 PyObject* objectFactory;
1346 PyObject* strObj;
1347 PyObject* valueFactory;
1348 if(!PyArg_ParseTuple(args, STRCAST("O!OO!"), objectFactoryType, &objectFactory, &strObj, valueFactoryType,
1349 &valueFactory))
1350 {
1351 return 0;
1352 }
1353
1354 string id;
1355 if(!getStringArg(strObj, "id", id))
1356 {
1357 return 0;
1358 }
1359
1360 ValueFactoryManagerPtr vfm = ValueFactoryManagerPtr::dynamicCast((*self->communicator)->getValueFactoryManager());
1361 assert(vfm);
1362
1363 try
1364 {
1365 vfm->add(valueFactory, objectFactory, id);
1366 }
1367 catch(const Ice::Exception& ex)
1368 {
1369 setPythonException(ex);
1370 return 0;
1371
1372 }
1373
1374 Py_INCREF(Py_None);
1375 return Py_None;
1376 }
1377
1378 #ifdef WIN32
1379 extern "C"
1380 #endif
1381 static PyObject*
communicatorFindObjectFactory(CommunicatorObject * self,PyObject * args)1382 communicatorFindObjectFactory(CommunicatorObject* self, PyObject* args)
1383 {
1384 PyObject* strObj;
1385 if(!PyArg_ParseTuple(args, STRCAST("O"), &strObj))
1386 {
1387 return 0;
1388 }
1389
1390 string id;
1391 if(!getStringArg(strObj, "id", id))
1392 {
1393 return 0;
1394 }
1395
1396 ValueFactoryManagerPtr vfm = ValueFactoryManagerPtr::dynamicCast((*self->communicator)->getValueFactoryManager());
1397 assert(vfm);
1398
1399 return vfm->findObjectFactory(id);
1400 }
1401
1402 #ifdef WIN32
1403 extern "C"
1404 #endif
1405 static PyObject*
communicatorGetValueFactoryManager(CommunicatorObject * self,PyObject *)1406 communicatorGetValueFactoryManager(CommunicatorObject* self, PyObject* /*args*/)
1407 {
1408 ValueFactoryManagerPtr vfm = ValueFactoryManagerPtr::dynamicCast((*self->communicator)->getValueFactoryManager());
1409
1410 return vfm->getObject();
1411 }
1412
1413 #ifdef WIN32
1414 extern "C"
1415 #endif
1416 static PyObject*
communicatorGetImplicitContext(CommunicatorObject * self,PyObject *)1417 communicatorGetImplicitContext(CommunicatorObject* self, PyObject* /*args*/)
1418 {
1419 Ice::ImplicitContextPtr implicitContext = (*self->communicator)->getImplicitContext();
1420
1421 if(implicitContext == 0)
1422 {
1423 Py_INCREF(Py_None);
1424 return Py_None;
1425 }
1426
1427 return createImplicitContext(implicitContext);
1428 }
1429
1430 #ifdef WIN32
1431 extern "C"
1432 #endif
1433 static PyObject*
communicatorCreateObjectAdapter(CommunicatorObject * self,PyObject * args)1434 communicatorCreateObjectAdapter(CommunicatorObject* self, PyObject* args)
1435 {
1436 PyObject* strObj;
1437 if(!PyArg_ParseTuple(args, STRCAST("O"), &strObj))
1438 {
1439 return 0;
1440 }
1441
1442 string name;
1443 if(!getStringArg(strObj, "name", name))
1444 {
1445 return 0;
1446 }
1447
1448 assert(self->communicator);
1449 Ice::ObjectAdapterPtr adapter;
1450 try
1451 {
1452 adapter = (*self->communicator)->createObjectAdapter(name);
1453 }
1454 catch(const Ice::Exception& ex)
1455 {
1456 setPythonException(ex);
1457 return 0;
1458 }
1459
1460 PyObject* obj = createObjectAdapter(adapter);
1461 if(!obj)
1462 {
1463 try
1464 {
1465 adapter->deactivate();
1466 }
1467 catch(const Ice::Exception&)
1468 {
1469 }
1470 }
1471
1472 return obj;
1473 }
1474
1475 #ifdef WIN32
1476 extern "C"
1477 #endif
1478 static PyObject*
communicatorCreateObjectAdapterWithEndpoints(CommunicatorObject * self,PyObject * args)1479 communicatorCreateObjectAdapterWithEndpoints(CommunicatorObject* self, PyObject* args)
1480 {
1481 PyObject* nameObj;
1482 PyObject* endpointsObj;
1483 if(!PyArg_ParseTuple(args, STRCAST("OO"), &nameObj, &endpointsObj))
1484 {
1485 return 0;
1486 }
1487
1488 string name;
1489 string endpoints;
1490 if(!getStringArg(nameObj, "name", name))
1491 {
1492 return 0;
1493 }
1494 if(!getStringArg(endpointsObj, "endpoints", endpoints))
1495 {
1496 return 0;
1497 }
1498
1499 assert(self->communicator);
1500 Ice::ObjectAdapterPtr adapter;
1501 try
1502 {
1503 adapter = (*self->communicator)->createObjectAdapterWithEndpoints(name, endpoints);
1504 }
1505 catch(const Ice::Exception& ex)
1506 {
1507 setPythonException(ex);
1508 return 0;
1509 }
1510
1511 PyObject* obj = createObjectAdapter(adapter);
1512 if(!obj)
1513 {
1514 try
1515 {
1516 adapter->deactivate();
1517 }
1518 catch(const Ice::Exception&)
1519 {
1520 }
1521 }
1522
1523 return obj;
1524 }
1525
1526 #ifdef WIN32
1527 extern "C"
1528 #endif
1529 static PyObject*
communicatorCreateObjectAdapterWithRouter(CommunicatorObject * self,PyObject * args)1530 communicatorCreateObjectAdapterWithRouter(CommunicatorObject* self, PyObject* args)
1531 {
1532 PyObject* nameObj;
1533 PyObject* p;
1534 if(!PyArg_ParseTuple(args, STRCAST("OO"), &nameObj, &p))
1535 {
1536 return 0;
1537 }
1538
1539 string name;
1540 if(!getStringArg(nameObj, "name", name))
1541 {
1542 return 0;
1543 }
1544
1545 Ice::ObjectPrx proxy;
1546 if(!getProxyArg(p, "createObjectAdapterWithRouter", "rtr", proxy, "Ice.RouterPrx"))
1547 {
1548 return 0;
1549 }
1550
1551 Ice::RouterPrx router = Ice::RouterPrx::uncheckedCast(proxy);
1552
1553 assert(self->communicator);
1554 Ice::ObjectAdapterPtr adapter;
1555 try
1556 {
1557 AllowThreads allowThreads; // Release Python's global interpreter lock to avoid a potential deadlock.
1558 adapter = (*self->communicator)->createObjectAdapterWithRouter(name, router);
1559 }
1560 catch(const Ice::Exception& ex)
1561 {
1562 setPythonException(ex);
1563 return 0;
1564 }
1565
1566 PyObject* obj = createObjectAdapter(adapter);
1567 if(!obj)
1568 {
1569 try
1570 {
1571 adapter->deactivate();
1572 }
1573 catch(const Ice::Exception&)
1574 {
1575 }
1576 }
1577
1578 return obj;
1579 }
1580
1581 #ifdef WIN32
1582 extern "C"
1583 #endif
1584 static PyObject*
communicatorGetDefaultRouter(CommunicatorObject * self,PyObject *)1585 communicatorGetDefaultRouter(CommunicatorObject* self, PyObject* /*args*/)
1586 {
1587 assert(self->communicator);
1588 Ice::RouterPrx router;
1589 try
1590 {
1591 router = (*self->communicator)->getDefaultRouter();
1592 }
1593 catch(const Ice::Exception& ex)
1594 {
1595 setPythonException(ex);
1596 return 0;
1597 }
1598
1599 if(!router)
1600 {
1601 Py_INCREF(Py_None);
1602 return Py_None;
1603 }
1604
1605 PyObject* routerProxyType = lookupType("Ice.RouterPrx");
1606 assert(routerProxyType);
1607 return createProxy(router, *self->communicator, routerProxyType);
1608 }
1609
1610 #ifdef WIN32
1611 extern "C"
1612 #endif
1613 static PyObject*
communicatorSetDefaultRouter(CommunicatorObject * self,PyObject * args)1614 communicatorSetDefaultRouter(CommunicatorObject* self, PyObject* args)
1615 {
1616 PyObject* p;
1617 if(!PyArg_ParseTuple(args, STRCAST("O"), &p))
1618 {
1619 return 0;
1620 }
1621
1622 Ice::ObjectPrx proxy;
1623 if(!getProxyArg(p, "setDefaultRouter", "rtr", proxy, "Ice.RouterPrx"))
1624 {
1625 return 0;
1626 }
1627
1628 Ice::RouterPrx router = Ice::RouterPrx::uncheckedCast(proxy);
1629
1630 assert(self->communicator);
1631 try
1632 {
1633 (*self->communicator)->setDefaultRouter(router);
1634 }
1635 catch(const Ice::Exception& ex)
1636 {
1637 setPythonException(ex);
1638 return 0;
1639 }
1640
1641 Py_INCREF(Py_None);
1642 return Py_None;
1643 }
1644
1645 #ifdef WIN32
1646 extern "C"
1647 #endif
1648 static PyObject*
communicatorGetDefaultLocator(CommunicatorObject * self,PyObject *)1649 communicatorGetDefaultLocator(CommunicatorObject* self, PyObject* /*args*/)
1650 {
1651 assert(self->communicator);
1652 Ice::LocatorPrx locator;
1653 try
1654 {
1655 locator = (*self->communicator)->getDefaultLocator();
1656 }
1657 catch(const Ice::Exception& ex)
1658 {
1659 setPythonException(ex);
1660 return 0;
1661 }
1662
1663 if(!locator)
1664 {
1665 Py_INCREF(Py_None);
1666 return Py_None;
1667 }
1668
1669 PyObject* locatorProxyType = lookupType("Ice.LocatorPrx");
1670 assert(locatorProxyType);
1671 return createProxy(locator, *self->communicator, locatorProxyType);
1672 }
1673
1674 #ifdef WIN32
1675 extern "C"
1676 #endif
1677 static PyObject*
communicatorSetDefaultLocator(CommunicatorObject * self,PyObject * args)1678 communicatorSetDefaultLocator(CommunicatorObject* self, PyObject* args)
1679 {
1680 PyObject* p;
1681 if(!PyArg_ParseTuple(args, STRCAST("O"), &p))
1682 {
1683 return 0;
1684 }
1685
1686 Ice::ObjectPrx proxy;
1687 if(!getProxyArg(p, "setDefaultLocator", "loc", proxy, "Ice.LocatorPrx"))
1688 {
1689 return 0;
1690 }
1691
1692 Ice::LocatorPrx locator = Ice::LocatorPrx::uncheckedCast(proxy);
1693
1694 assert(self->communicator);
1695 try
1696 {
1697 (*self->communicator)->setDefaultLocator(locator);
1698 }
1699 catch(const Ice::Exception& ex)
1700 {
1701 setPythonException(ex);
1702 return 0;
1703 }
1704
1705 Py_INCREF(Py_None);
1706 return Py_None;
1707 }
1708
1709 static PyMethodDef CommunicatorMethods[] =
1710 {
1711 { STRCAST("destroy"), reinterpret_cast<PyCFunction>(communicatorDestroy), METH_NOARGS,
1712 PyDoc_STR(STRCAST("destroy() -> None")) },
1713 { STRCAST("shutdown"), reinterpret_cast<PyCFunction>(communicatorShutdown), METH_NOARGS,
1714 PyDoc_STR(STRCAST("shutdown() -> None")) },
1715 { STRCAST("waitForShutdown"), reinterpret_cast<PyCFunction>(communicatorWaitForShutdown), METH_VARARGS,
1716 PyDoc_STR(STRCAST("waitForShutdown() -> None")) },
1717 { STRCAST("isShutdown"), reinterpret_cast<PyCFunction>(communicatorIsShutdown), METH_NOARGS,
1718 PyDoc_STR(STRCAST("isShutdown() -> bool")) },
1719 { STRCAST("stringToProxy"), reinterpret_cast<PyCFunction>(communicatorStringToProxy), METH_VARARGS,
1720 PyDoc_STR(STRCAST("stringToProxy(str) -> Ice.ObjectPrx")) },
1721 { STRCAST("proxyToString"), reinterpret_cast<PyCFunction>(communicatorProxyToString), METH_VARARGS,
1722 PyDoc_STR(STRCAST("proxyToString(Ice.ObjectPrx) -> string")) },
1723 { STRCAST("propertyToProxy"), reinterpret_cast<PyCFunction>(communicatorPropertyToProxy), METH_VARARGS,
1724 PyDoc_STR(STRCAST("propertyToProxy(str) -> Ice.ObjectPrx")) },
1725 { STRCAST("proxyToProperty"), reinterpret_cast<PyCFunction>(communicatorProxyToProperty), METH_VARARGS,
1726 PyDoc_STR(STRCAST("proxyToProperty(Ice.ObjectPrx, str) -> dict")) },
1727 { STRCAST("stringToIdentity"), reinterpret_cast<PyCFunction>(communicatorStringToIdentity), METH_VARARGS,
1728 PyDoc_STR(STRCAST("stringToIdentity(str) -> Ice.Identity")) },
1729 { STRCAST("identityToString"), reinterpret_cast<PyCFunction>(communicatorIdentityToString), METH_VARARGS,
1730 PyDoc_STR(STRCAST("identityToString(Ice.Identity) -> string")) },
1731 { STRCAST("createObjectAdapter"), reinterpret_cast<PyCFunction>(communicatorCreateObjectAdapter), METH_VARARGS,
1732 PyDoc_STR(STRCAST("createObjectAdapter(name) -> Ice.ObjectAdapter")) },
1733 { STRCAST("createObjectAdapterWithEndpoints"),
1734 reinterpret_cast<PyCFunction>(communicatorCreateObjectAdapterWithEndpoints), METH_VARARGS,
1735 PyDoc_STR(STRCAST("createObjectAdapterWithEndpoints(name, endpoints) -> Ice.ObjectAdapter")) },
1736 { STRCAST("createObjectAdapterWithRouter"),
1737 reinterpret_cast<PyCFunction>(communicatorCreateObjectAdapterWithRouter), METH_VARARGS,
1738 PyDoc_STR(STRCAST("createObjectAdapterWithRouter(name, router) -> Ice.ObjectAdapter")) },
1739 { STRCAST("addObjectFactory"), reinterpret_cast<PyCFunction>(communicatorAddObjectFactory), METH_VARARGS,
1740 PyDoc_STR(STRCAST("addObjectFactory(factory, id) -> None")) },
1741 { STRCAST("findObjectFactory"), reinterpret_cast<PyCFunction>(communicatorFindObjectFactory), METH_VARARGS,
1742 PyDoc_STR(STRCAST("findObjectFactory(id) -> Ice.ObjectFactory")) },
1743 { STRCAST("getValueFactoryManager"), reinterpret_cast<PyCFunction>(communicatorGetValueFactoryManager), METH_NOARGS,
1744 PyDoc_STR(STRCAST("getValueFactoryManager() -> Ice.ValueFactoryManager")) },
1745 { STRCAST("getImplicitContext"), reinterpret_cast<PyCFunction>(communicatorGetImplicitContext), METH_NOARGS,
1746 PyDoc_STR(STRCAST("getImplicitContext() -> Ice.ImplicitContext")) },
1747 { STRCAST("getProperties"), reinterpret_cast<PyCFunction>(communicatorGetProperties), METH_NOARGS,
1748 PyDoc_STR(STRCAST("getProperties() -> Ice.Properties")) },
1749 { STRCAST("getLogger"), reinterpret_cast<PyCFunction>(communicatorGetLogger), METH_NOARGS,
1750 PyDoc_STR(STRCAST("getLogger() -> Ice.Logger")) },
1751 { STRCAST("getDefaultRouter"), reinterpret_cast<PyCFunction>(communicatorGetDefaultRouter), METH_NOARGS,
1752 PyDoc_STR(STRCAST("getDefaultRouter() -> proxy")) },
1753 { STRCAST("setDefaultRouter"), reinterpret_cast<PyCFunction>(communicatorSetDefaultRouter), METH_VARARGS,
1754 PyDoc_STR(STRCAST("setDefaultRouter(proxy) -> None")) },
1755 { STRCAST("getDefaultLocator"), reinterpret_cast<PyCFunction>(communicatorGetDefaultLocator), METH_NOARGS,
1756 PyDoc_STR(STRCAST("getDefaultLocator() -> proxy")) },
1757 { STRCAST("setDefaultLocator"), reinterpret_cast<PyCFunction>(communicatorSetDefaultLocator), METH_VARARGS,
1758 PyDoc_STR(STRCAST("setDefaultLocator(proxy) -> None")) },
1759 { STRCAST("flushBatchRequests"), reinterpret_cast<PyCFunction>(communicatorFlushBatchRequests), METH_VARARGS,
1760 PyDoc_STR(STRCAST("flushBatchRequests(compress) -> None")) },
1761 { STRCAST("flushBatchRequestsAsync"), reinterpret_cast<PyCFunction>(communicatorFlushBatchRequestsAsync),
1762 METH_VARARGS, PyDoc_STR(STRCAST("flushBatchRequestsAsync(compress) -> Ice.Future")) },
1763 { STRCAST("begin_flushBatchRequests"), reinterpret_cast<PyCFunction>(communicatorBeginFlushBatchRequests),
1764 METH_VARARGS | METH_KEYWORDS,
1765 PyDoc_STR(STRCAST("begin_flushBatchRequests(compress[, _ex][, _sent]) -> Ice.AsyncResult")) },
1766 { STRCAST("end_flushBatchRequests"), reinterpret_cast<PyCFunction>(communicatorEndFlushBatchRequests),
1767 METH_VARARGS, PyDoc_STR(STRCAST("end_flushBatchRequests(Ice.AsyncResult) -> None")) },
1768 { STRCAST("createAdmin"), reinterpret_cast<PyCFunction>(communicatorCreateAdmin), METH_VARARGS,
1769 PyDoc_STR(STRCAST("createAdmin(adminAdapter, adminIdentity) -> Ice.ObjectPrx")) },
1770 { STRCAST("getAdmin"), reinterpret_cast<PyCFunction>(communicatorGetAdmin), METH_NOARGS,
1771 PyDoc_STR(STRCAST("getAdmin() -> Ice.ObjectPrx")) },
1772 { STRCAST("addAdminFacet"), reinterpret_cast<PyCFunction>(communicatorAddAdminFacet), METH_VARARGS,
1773 PyDoc_STR(STRCAST("addAdminFacet(servant, facet) -> None")) },
1774 { STRCAST("findAdminFacet"), reinterpret_cast<PyCFunction>(communicatorFindAdminFacet), METH_VARARGS,
1775 PyDoc_STR(STRCAST("findAdminFacet(facet) -> Ice.Object")) },
1776 { STRCAST("findAllAdminFacets"), reinterpret_cast<PyCFunction>(communicatorFindAllAdminFacets), METH_NOARGS,
1777 PyDoc_STR(STRCAST("findAllAdminFacets() -> dictionary")) },
1778 { STRCAST("removeAdminFacet"), reinterpret_cast<PyCFunction>(communicatorRemoveAdminFacet), METH_VARARGS,
1779 PyDoc_STR(STRCAST("removeAdminFacet(facet) -> Ice.Object")) },
1780 { STRCAST("_setWrapper"), reinterpret_cast<PyCFunction>(communicatorSetWrapper), METH_VARARGS,
1781 PyDoc_STR(STRCAST("internal function")) },
1782 { STRCAST("_getWrapper"), reinterpret_cast<PyCFunction>(communicatorGetWrapper), METH_NOARGS,
1783 PyDoc_STR(STRCAST("internal function")) },
1784 { 0, 0 } /* sentinel */
1785 };
1786
1787 namespace IcePy
1788 {
1789
1790 PyTypeObject CommunicatorType =
1791 {
1792 /* The ob_type field must be initialized in the module init function
1793 * to be portable to Windows without using C++. */
1794 PyVarObject_HEAD_INIT(0, 0)
1795 STRCAST("IcePy.Communicator"), /* tp_name */
1796 sizeof(CommunicatorObject), /* tp_basicsize */
1797 0, /* tp_itemsize */
1798 /* methods */
1799 reinterpret_cast<destructor>(communicatorDealloc), /* tp_dealloc */
1800 0, /* tp_print */
1801 0, /* tp_getattr */
1802 0, /* tp_setattr */
1803 0, /* tp_reserved */
1804 0, /* tp_repr */
1805 0, /* tp_as_number */
1806 0, /* tp_as_sequence */
1807 0, /* tp_as_mapping */
1808 0, /* tp_hash */
1809 0, /* tp_call */
1810 0, /* tp_str */
1811 0, /* tp_getattro */
1812 0, /* tp_setattro */
1813 0, /* tp_as_buffer */
1814 Py_TPFLAGS_DEFAULT, /* tp_flags */
1815 0, /* tp_doc */
1816 0, /* tp_traverse */
1817 0, /* tp_clear */
1818 0, /* tp_richcompare */
1819 0, /* tp_weaklistoffset */
1820 0, /* tp_iter */
1821 0, /* tp_iternext */
1822 CommunicatorMethods, /* tp_methods */
1823 0, /* tp_members */
1824 0, /* tp_getset */
1825 0, /* tp_base */
1826 0, /* tp_dict */
1827 0, /* tp_descr_get */
1828 0, /* tp_descr_set */
1829 0, /* tp_dictoffset */
1830 reinterpret_cast<initproc>(communicatorInit), /* tp_init */
1831 0, /* tp_alloc */
1832 reinterpret_cast<newfunc>(communicatorNew), /* tp_new */
1833 0, /* tp_free */
1834 0, /* tp_is_gc */
1835 };
1836
1837 }
1838
1839 bool
initCommunicator(PyObject * module)1840 IcePy::initCommunicator(PyObject* module)
1841 {
1842 _mainThreadId = PyThread_get_thread_ident();
1843
1844 if(PyType_Ready(&CommunicatorType) < 0)
1845 {
1846 return false;
1847 }
1848 PyTypeObject* type = &CommunicatorType; // Necessary to prevent GCC's strict-alias warnings.
1849 if(PyModule_AddObject(module, STRCAST("Communicator"), reinterpret_cast<PyObject*>(type)) < 0)
1850 {
1851 return false;
1852 }
1853
1854 return true;
1855 }
1856
1857 Ice::CommunicatorPtr
getCommunicator(PyObject * obj)1858 IcePy::getCommunicator(PyObject* obj)
1859 {
1860 assert(PyObject_IsInstance(obj, reinterpret_cast<PyObject*>(&CommunicatorType)));
1861 CommunicatorObject* cobj = reinterpret_cast<CommunicatorObject*>(obj);
1862 return *cobj->communicator;
1863 }
1864
1865 PyObject*
createCommunicator(const Ice::CommunicatorPtr & communicator)1866 IcePy::createCommunicator(const Ice::CommunicatorPtr& communicator)
1867 {
1868 CommunicatorMap::iterator p = _communicatorMap.find(communicator);
1869 if(p != _communicatorMap.end())
1870 {
1871 Py_INCREF(p->second);
1872 return p->second;
1873 }
1874
1875 CommunicatorObject* obj = communicatorNew(&CommunicatorType, 0, 0);
1876 if(obj)
1877 {
1878 obj->communicator = new Ice::CommunicatorPtr(communicator);
1879 }
1880 return (PyObject*)obj;
1881 }
1882
1883 PyObject*
getCommunicatorWrapper(const Ice::CommunicatorPtr & communicator)1884 IcePy::getCommunicatorWrapper(const Ice::CommunicatorPtr& communicator)
1885 {
1886 CommunicatorMap::iterator p = _communicatorMap.find(communicator);
1887 assert(p != _communicatorMap.end());
1888 CommunicatorObject* obj = reinterpret_cast<CommunicatorObject*>(p->second);
1889 if(obj->wrapper)
1890 {
1891 Py_INCREF(obj->wrapper);
1892 return obj->wrapper;
1893 }
1894 else
1895 {
1896 //
1897 // Communicator must have been destroyed already.
1898 //
1899 Py_INCREF(Py_None);
1900 return Py_None;
1901 }
1902 }
1903
1904 extern "C"
1905 PyObject*
IcePy_identityToString(PyObject *,PyObject * args)1906 IcePy_identityToString(PyObject* /*self*/, PyObject* args)
1907 {
1908 PyObject* identityType = lookupType("Ice.Identity");
1909 PyObject* obj;
1910 PyObject* mode = 0;
1911 if(!PyArg_ParseTuple(args, STRCAST("O!O"), identityType, &obj, &mode))
1912 {
1913 return 0;
1914 }
1915
1916 Ice::Identity id;
1917 if(!getIdentity(obj, id))
1918 {
1919 return 0;
1920 }
1921
1922 Ice::ToStringMode toStringMode = Ice::Unicode;
1923 if(mode != Py_None && PyObject_HasAttrString(mode, STRCAST("value")))
1924 {
1925 PyObjectHandle modeValue = getAttr(mode, "value", true);
1926 toStringMode = static_cast<Ice::ToStringMode>(PyLong_AsLong(modeValue.get()));
1927 }
1928
1929 string str;
1930
1931 try
1932 {
1933 str = identityToString(id, toStringMode);
1934 }
1935 catch(const Ice::Exception& ex)
1936 {
1937 setPythonException(ex);
1938 return 0;
1939 }
1940
1941 return createString(str);
1942 }
1943
1944 extern "C"
1945 PyObject*
IcePy_stringToIdentity(PyObject *,PyObject * obj)1946 IcePy_stringToIdentity(PyObject* /*self*/, PyObject* obj)
1947 {
1948 string str;
1949 if(!getStringArg(obj, "str", str))
1950 {
1951 return 0;
1952 }
1953
1954 Ice::Identity id;
1955 try
1956 {
1957 id = Ice::stringToIdentity(str);
1958 }
1959 catch(const Ice::Exception& ex)
1960 {
1961 setPythonException(ex);
1962 return 0;
1963 }
1964
1965 return createIdentity(id);
1966 }
1967