3
// pyCallDescriptor.cc Created on: 2000/02/02
4
// Author : Duncan Grisby (dpg1)
6
// Copyright (C) 2000 AT&T Laboratories Cambridge
8
// This file is part of the omniORBpy library
10
// The omniORBpy library is free software; you can redistribute it
11
// and/or modify it under the terms of the GNU Lesser General
12
// Public License as published by the Free Software Foundation;
13
// either version 2.1 of the License, or (at your option) any later
16
// This library is distributed in the hope that it will be useful,
17
// but WITHOUT ANY WARRANTY; without even the implied warranty of
18
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
// GNU Lesser General Public License for more details.
21
// You should have received a copy of the GNU Lesser General Public
22
// License along with this library; if not, write to the Free
23
// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
28
// Implementation of Python call descriptor object
30
// $Id: pyCallDescriptor.cc,v 1.1.4.3 2005/01/07 00:22:32 dgrisby Exp $
31
// $Log: pyCallDescriptor.cc,v $
32
// Revision 1.1.4.3 2005/01/07 00:22:32 dgrisby
33
// Big merge from omnipy2_develop.
35
// Revision 1.1.4.2 2003/07/10 22:17:02 dgrisby
36
// Track orb core changes, fix bugs.
38
// Revision 1.1.4.1 2003/03/23 21:51:57 dgrisby
39
// New omnipy3_develop branch.
41
// Revision 1.1.2.11 2003/01/27 11:56:57 dgrisby
42
// Correctly handle invalid returns from application code.
44
// Revision 1.1.2.10 2002/01/18 15:49:44 dpg1
45
// Context support. New system exception construction. Fix None call problem.
47
// Revision 1.1.2.9 2001/09/24 10:48:25 dpg1
48
// Meaningful minor codes.
50
// Revision 1.1.2.8 2001/09/20 14:51:24 dpg1
51
// Allow ORB reinitialisation after destroy(). Clean up use of omni namespace.
53
// Revision 1.1.2.7 2001/08/15 10:37:14 dpg1
54
// Track ORB core object table changes.
56
// Revision 1.1.2.6 2001/06/29 15:11:12 dpg1
57
// Fix for clients using GIOP 1.0.
59
// Revision 1.1.2.5 2001/06/29 09:53:56 dpg1
60
// Fix for clients using GIOP 1.0.
62
// Revision 1.1.2.4 2001/06/01 11:09:26 dpg1
63
// Make use of new omni::ptrStrCmp() and omni::strCmp().
65
// Revision 1.1.2.3 2001/05/10 15:16:02 dpg1
66
// Big update to support new omniORB 4 internals.
68
// Revision 1.1.2.2 2001/01/10 12:00:07 dpg1
69
// Release the Python interpreter lock when doing potentially blocking
72
// Revision 1.1.2.1 2000/10/13 13:55:24 dpg1
73
// Initial support for omniORB 4.
77
#include <pyThreadCache.h>
78
#include <omniORB4/IOP_C.h>
80
#ifdef HAS_Cplusplus_Namespace
85
inline cdLockHolder(omniPy::Py_omniCallDescriptor* cd) : cd_(cd) {
86
cd->reacquireInterpreterLock();
88
inline ~cdLockHolder() {
89
cd_->releaseInterpreterLock();
92
omniPy::Py_omniCallDescriptor* cd_;
94
#ifdef HAS_Cplusplus_Namespace
99
OMNI_USING_NAMESPACE(omni)
102
omniPy::Py_omniCallDescriptor::~Py_omniCallDescriptor()
104
OMNIORB_ASSERT(!tstate_);
111
omniPy::Py_omniCallDescriptor::initialiseCall(cdrStream&)
113
// initialiseCall() is called with the interpreter lock
114
// released. Reacquire it so we can touch the descriptor objects
116
cdLockHolder _l(this);
118
for (int i=0; i < in_l_; i++)
119
omniPy::validateType(PyTuple_GET_ITEM(in_d_,i),
120
PyTuple_GET_ITEM(args_,i),
121
CORBA::COMPLETED_NO);
126
omniPy::Py_omniCallDescriptor::marshalArguments(cdrStream& stream)
130
omniORB::logs(25, "Python marshalArguments re-entered.");
132
// marshalArguments can be re-entered when using GIOP 1.0, to
133
// calculate the message size if the message is too big for a
134
// single buffer. In that case, the interpreter lock has been
135
// released by the PyUnlockingCdrStream, meaning the call
136
// descriptor does not have the lock details. We have to use the
137
// thread cache lock.
139
omnipyThreadCache::lock _t;
141
for (i=0; i < in_l_; i++)
142
omniPy::marshalPyObject(stream,
143
PyTuple_GET_ITEM(in_d_,i),
144
PyTuple_GET_ITEM(args_,i));
146
omniPy::marshalContext(stream, ctxt_d_, PyTuple_GET_ITEM(args_, i));
149
cdLockHolder _l(this);
152
PyUnlockingCdrStream pystream(stream);
155
for (i=0; i < in_l_; i++)
156
omniPy::marshalPyObject(pystream,
157
PyTuple_GET_ITEM(in_d_,i),
158
PyTuple_GET_ITEM(args_,i));
160
omniPy::marshalContext(pystream, ctxt_d_, PyTuple_GET_ITEM(args_, i));
172
omniPy::Py_omniCallDescriptor::unmarshalReturnedValues(cdrStream& stream)
174
if (out_l_ == -1) return; // Oneway operation
176
cdLockHolder _l(this);
183
PyUnlockingCdrStream pystream(stream);
186
result_ = omniPy::unmarshalPyObject(pystream,
187
PyTuple_GET_ITEM(out_d_, 0));
189
result_ = PyTuple_New(out_l_);
191
OMNIORB_THROW(NO_MEMORY, 0,
192
(CORBA::CompletionStatus)stream.completion());
194
for (int i=0; i < out_l_; i++) {
195
PyTuple_SET_ITEM(result_, i,
196
omniPy::unmarshalPyObject(pystream,
197
PyTuple_GET_ITEM(out_d_,
206
omniPy::Py_omniCallDescriptor::userException(cdrStream& stream,
210
reacquireInterpreterLock();
212
PyObject* d_o = PyDict_GetItemString(exc_d_, (char*)repoId);
214
if (d_o) { // class, repoId, exc name, name, descriptor, ...
217
PyUserException ex(d_o);
223
releaseInterpreterLock();
224
if (iop_client) iop_client->RequestCompleted();
227
OMNIORB_ASSERT(0); // Never reach here
230
releaseInterpreterLock();
231
if (iop_client) iop_client->RequestCompleted(1);
232
OMNIORB_THROW(UNKNOWN, UNKNOWN_UserException,
233
(CORBA::CompletionStatus)stream.completion());
239
omniPy::Py_localCallBackFunction(omniCallDescriptor* cd, omniServant* svnt)
241
Py_omniCallDescriptor* pycd = (Py_omniCallDescriptor*)cd;
242
Py_omniServant* pyos =
243
(Py_omniServant*)svnt->_ptrToInterface(omniPy::string_Py_omniServant);
245
// Unfortunately, we can't use the call descriptor's
246
// reacquireInterpreterLock() function, since this call-back may be
247
// running in a different thread to the creator of the call
250
if (cd->is_upcall()) {
251
omnipyThreadCache::lock _t;
252
pyos->remote_dispatch(pycd);
255
omnipyThreadCache::lock _t;
256
pyos->local_dispatch(pycd);
262
omniPy::Py_omniCallDescriptor::unmarshalArguments(cdrStream& stream)
264
OMNIORB_ASSERT(args_ == 0);
266
omnipyThreadCache::lock _t;
269
args_ = PyTuple_New(in_l_ + 1);
271
args_ = PyTuple_New(in_l_);
274
PyUnlockingCdrStream pystream(stream);
277
for (i=0; i < in_l_; i++) {
278
PyTuple_SET_ITEM(args_, i,
279
omniPy::unmarshalPyObject(pystream,
280
PyTuple_GET_ITEM(in_d_, i)));
283
PyTuple_SET_ITEM(args_, i, omniPy::unmarshalContext(pystream));
287
omniPy::Py_omniCallDescriptor::setAndValidateReturnedValues(PyObject* result)
289
OMNIORB_ASSERT(result_ == 0);
292
if (out_l_ == -1 || out_l_ == 0) {
293
if (result_ != Py_None)
294
OMNIORB_THROW(BAD_PARAM,
295
BAD_PARAM_WrongPythonType,
296
CORBA::COMPLETED_MAYBE);
298
else if (out_l_ == 1) {
299
omniPy::validateType(PyTuple_GET_ITEM(out_d_,0),
301
CORBA::COMPLETED_MAYBE);
304
if (!PyTuple_Check(result) || PyTuple_GET_SIZE(result) != out_l_)
305
OMNIORB_THROW(BAD_PARAM,
306
BAD_PARAM_WrongPythonType,
307
CORBA::COMPLETED_MAYBE);
309
for (int i=0; i < out_l_; i++) {
310
omniPy::validateType(PyTuple_GET_ITEM(out_d_,i),
311
PyTuple_GET_ITEM(result,i),
312
CORBA::COMPLETED_MAYBE);
318
omniPy::Py_omniCallDescriptor::marshalReturnedValues(cdrStream& stream)
320
omnipyThreadCache::lock _t;
321
PyUnlockingCdrStream pystream(stream);
324
omniPy::marshalPyObject(pystream,
325
PyTuple_GET_ITEM(out_d_, 0),
329
for (int i=0; i < out_l_; i++) {
330
omniPy::marshalPyObject(pystream,
331
PyTuple_GET_ITEM(out_d_,i),
332
PyTuple_GET_ITEM(result_,i));