pytorch/torch/csrc/utils/object_ptr.h
Dmytro Dzhulgakov 92f70bb639 Split python_ir.h in a more sensible way (#19081)
Summary:
Files included in libtorch do depend on torch/csrc/utils/object_ptr.h, e.g. ir.cpp: https://github.com/pytorch/pytorch/blob/master/torch/csrc/jit/ir.h#L10 (including usage in std::vector that requires destructor for THPPointer)

However, object_ptr.h depends on python stub: https://github.com/pytorch/pytorch/blob/master/torch/csrc/utils/object_ptr.h#L3

Whereas object_ptr.cpp depends full on on python: https://github.com/pytorch/pytorch/blob/master/torch/csrc/utils/object_ptr.cpp#L8

`torch/csrc/utils/object_ptr.cpp` is included only in Python extension target: https://github.com/pytorch/pytorch/blob/master/torch/CMakeLists.txt#L541

The only reason it was working on master is that compiler was aggressive enough in pruning unused inline functions. With a bit of changes in flags, it started breaking (like in kostmo's PR).

This PR splits out python-dependent bits more explicitly by forward declaring THPPointer for real.
Pull Request resolved: https://github.com/pytorch/pytorch/pull/19081

Reviewed By: ezyang

Differential Revision: D14860091

Pulled By: dzhulgakov

fbshipit-source-id: 4e86cb8e2ac57aedb3cd00c15270d65bb376206c
2019-04-10 10:26:50 -07:00

39 lines
1.3 KiB
C++

#pragma once
#include <torch/csrc/python_headers.h>
template<class T>
class THPPointer {
public:
THPPointer(): ptr(nullptr) {};
explicit THPPointer(T *ptr) noexcept : ptr(ptr) {};
THPPointer(THPPointer &&p) noexcept { free(); ptr = p.ptr; p.ptr = nullptr; };
~THPPointer() { free(); };
T * get() { return ptr; }
const T * get() const { return ptr; }
T * release() { T *tmp = ptr; ptr = nullptr; return tmp; }
operator T*() { return ptr; }
THPPointer& operator =(T *new_ptr) noexcept { free(); ptr = new_ptr; return *this; }
THPPointer& operator =(THPPointer &&p) noexcept { free(); ptr = p.ptr; p.ptr = nullptr; return *this; }
T * operator ->() { return ptr; }
explicit operator bool() const { return ptr != nullptr; }
private:
void free();
T *ptr = nullptr;
};
/**
* An RAII-style, owning pointer to a PyObject. You must protect
* destruction of this object with the GIL.
*
* WARNING: Think twice before putting this as a field in a C++
* struct. This class does NOT take out the GIL on destruction,
* so if you will need to ensure that the destructor of your struct
* is either (a) always invoked when the GIL is taken or (b) takes
* out the GIL itself. Easiest way to avoid this problem is to
* not use THPPointer in this situation.
*/
using THPObjectPtr = THPPointer<PyObject>;