#include <python.h>

static int dosomething()
{
  int attribute_found = 0;


  // Somewhere in the call stack we want to call Python
  // (a common case of embedding Python accoirding PEP 311)
  PyGILState_STATE state = PyGILState_Ensure();
  // Now we are safe and can call python APIs,
  // and the code below is executed in the context
  // of pystate.c->autoInterpreterState
  {
    /* does the same as
       import sys
       if hasattr(sys, "testAttr"):
         print sys.testAttr
       else:
         print "attribute not found"
    */
    PyObject* sys = PyImport_ImportModule("sys");

    if (PyObject_HasAttrString(sys, "testAttr")) {
      PyObject *testAttr = PyObject_GetAttrString(sys, "testAttr");
      PyObject *testAttr_str = PyObject_Str(testAttr);
      printf("sys.testAttr = %s\n", PyString_AsString(testAttr_str));
      Py_DECREF(testAttr_str);
      Py_DECREF(testAttr);
      attribute_found = 1;
    } else {
      printf("sys.testAttr does not exist.");
    }

    Py_DECREF(sys);
  }
  PyGILState_Release(state);

  return attribute_found;
}

static PyObject *test_funct1(PyObject *self, PyObject *args)
{
  int attribute_found = 0;
  /*
     import sys
     sys.testAttr = "testAttr"
  */
  PyObject* sys = PyImport_ImportModule("sys");
  PyObject* testAttr = PyString_FromString("testAttr");
  PyObject_SetAttrString(sys, "testAttr", testAttr);
  Py_DECREF(testAttr);
  Py_DECREF(sys);

  // Now let's do something time consuming, so we have to
  // allow the other threads executing Python code to run
  Py_BEGIN_ALLOW_THREADS
     // now we do not have any python thread state...
     attribute_found = dosomething();
  Py_END_ALLOW_THREADS

  return Py_BuildValue("i", attribute_found);
}

static PyMethodDef gil_testMethods[] =
{
  {"funct1", test_funct1, METH_NOARGS, ""},
  {NULL, NULL}
};

DL_EXPORT(void) initgil_test()
{
  Py_InitModule("gil_test", gil_testMethods);
}

/*
import gil_test
attribute_found = gil_test.funct1()
print 'attribute_found =', attribute_found
*/
