1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
/* -*-c++-*-
*
* $Id: Callback.cc,v 1.2 2003/02/11 23:52:12 dairiki Exp $
*
* Copyright (C) 2003 Geoffrey T. Dairiki
*
* This file is part of Pyxine, Python bindings for xine.
*
* Pyxine is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* Pyxine is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#pragma implementation
#include "Callback.h"
BEGIN_PXLIB_NAMESPACE
////////////////////////////////////////////////////////////////
PythonObject::PythonObject (PyObject * object, bool owned)
: ptr(object)
{
if (!object) throw PythonException();
if (!owned) { Py_INCREF(ptr); }
}
PythonObject::PythonObject (const PythonObject& that)
: ptr(that.ptr)
{
if (ptr) { Py_INCREF(ptr); }
}
PythonObject&
PythonObject::operator= (const PythonObject& that)
{
if (ptr) { Py_DECREF(ptr); }
ptr = that.ptr;
if (ptr) { Py_INCREF(ptr); }
return *this;
}
PythonObject::~PythonObject()
{
if (ptr) { Py_DECREF(ptr); }
}
////////////////////////////////////////////////////////////////
PythonContext::rep_t::rep_t()
: ref_cnt(1)
{
// You must call this from a python thread.
PyEval_InitThreads();
state = PyThreadState_New(PyThreadState_Get()->interp);
if (!state)
throw Error("PyThreadState_New failed");
PyThreadState_Clear(state);
}
PythonContext::rep_t::~rep_t()
{
PyThreadState_Delete(state);
}
PythonContext::PythonContext()
: rep(new rep_t) // You must call this from a python thread.
{}
PythonContext::PythonContext(const PythonContext& c)
: rep(c.rep)
{
rep->ref_cnt++;
}
PythonContext::PythonContext&
PythonContext::operator=(const PythonContext& c)
{
if (--rep->ref_cnt == 0)
delete rep;
rep = c.rep;
rep->ref_cnt++;
return *this;
}
PythonContext::~PythonContext ()
{
if (--rep->ref_cnt == 0)
delete rep;
}
////////////////////////////////////////////////////////////////
PythonGlobalLock::PythonGlobalLock(PythonContext& _context)
: mutex_lock(_context),
context(_context)
{
// WARNING: You must not be in a python thread when this is called.
PyEval_AcquireLock();
saved_state = PyThreadState_Swap(context);
}
PythonGlobalLock::~PythonGlobalLock()
{
// Report any pending exception
// (This is redundant. Exceptions should be reported and clears
// when (the C++ exception) PythonException is thrown.
if (PyErr_Occurred())
PyErr_Print();
PyThreadState_Swap(saved_state);
PyThreadState_Clear(context);
PyEval_ReleaseLock();
}
END_PXLIB_NAMESPACE
|