Apache Mesos
common.hpp
Go to the documentation of this file.
1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 
17 #ifndef MESOS_NATIVE_COMMON_HPP
18 #define MESOS_NATIVE_COMMON_HPP
19 
20 // Python.h must be included before standard headers.
21 // See: http://docs.python.org/2/c-api/intro.html#include-files
22 #include <Python.h>
23 
24 #include <iostream>
25 
26 #include <google/protobuf/io/zero_copy_stream_impl.h>
27 
28 
29 namespace mesos { namespace python {
30 
35 extern PyObject* mesos_pb2;
36 
37 
42  PyGILState_STATE state;
43 
44 public:
46  state = PyGILState_Ensure();
47  }
48 
50  PyGILState_Release(state);
51  }
52 };
53 
54 
60 template <typename T>
61 bool readPythonProtobuf(PyObject* obj, T* t)
62 {
63  if (obj == Py_None) {
64  std::cerr << "None object given where protobuf expected" << std::endl;
65  return false;
66  }
67  PyObject* res = PyObject_CallMethod(obj,
68  (char*) "SerializeToString",
69  (char*) nullptr);
70  if (res == nullptr) {
71  std::cerr << "Failed to call Python object's SerializeToString "
72  << "(perhaps it is not a protobuf?)" << std::endl;
73  PyErr_Print();
74  return false;
75  }
76  char* chars;
77  Py_ssize_t len;
78  if (PyString_AsStringAndSize(res, &chars, &len) < 0) {
79  std::cerr << "SerializeToString did not return a string" << std::endl;
80  PyErr_Print();
81  Py_DECREF(res);
82  return false;
83  }
84  google::protobuf::io::ArrayInputStream stream(chars, len);
85  bool success = t->ParseFromZeroCopyStream(&stream);
86  if (!success) {
87  std::cerr << "Could not deserialize protobuf as expected type" << std::endl;
88  }
89  Py_DECREF(res);
90  return success;
91 }
92 
93 
100 template <typename T>
101 PyObject* createPythonProtobuf(const T& t, const char* typeName)
102 {
103  PyObject* dict = PyModule_GetDict(mesos_pb2);
104  if (dict == nullptr) {
105  PyErr_Format(PyExc_Exception, "PyModule_GetDict failed");
106  return nullptr;
107  }
108 
109  PyObject* type = PyDict_GetItemString(dict, typeName);
110  if (type == nullptr) {
111  PyErr_Format(PyExc_Exception, "Could not resolve mesos_pb2.%s", typeName);
112  return nullptr;
113  }
114  if (!PyType_Check(type)) {
115  PyErr_Format(PyExc_Exception, "mesos_pb2.%s is not a type", typeName);
116  return nullptr;
117  }
118 
119  std::string str;
120  if (!t.SerializeToString(&str)) {
121  PyErr_Format(PyExc_Exception, "C++ %s SerializeToString failed", typeName);
122  return nullptr;
123  }
124 
125  // Propagates any exception that might happen in FromString.
126  return PyObject_CallMethod(type,
127  (char*) "FromString",
128  (char*) "s#",
129  str.data(),
130  str.size());
131 }
132 
133 } // namespace python {
134 } // namespace mesos {
135 
136 #endif /* MESOS_NATIVE_COMMON_HPP */
PyObject * createPythonProtobuf(const T &t, const char *typeName)
Convert a C++ protocol buffer object into a Python one by serializing it to a string and deserializin...
Definition: common.hpp:101
bool readPythonProtobuf(PyObject *obj, T *t)
Convert a Python protocol buffer object into a C++ one by serializing it to a string and deserializin...
Definition: common.hpp:61
Try< std::string > typeName(uint32_t fsType)
PyObject * mesos_pb2
The Python module object for mesos_pb2 (which contains the protobuf classes generated for Python)...
RAII utility class for acquiring the Python global interpreter lock.
Definition: common.hpp:41
~InterpreterLock()
Definition: common.hpp:49
Definition: spec.hpp:30
InterpreterLock()
Definition: common.hpp:45
Try< uint32_t > type(const std::string &path)