| 1850 | } |
| 1851 | |
| 1852 | void CSharpInstance::refcount_incremented() { |
| 1853 | #ifdef DEBUG_ENABLED |
| 1854 | CRASH_COND(!base_ref_counted); |
| 1855 | CRASH_COND(owner == nullptr); |
| 1856 | #endif // DEBUG_ENABLED |
| 1857 | |
| 1858 | RefCounted *rc_owner = Object::cast_to<RefCounted>(owner); |
| 1859 | |
| 1860 | if (rc_owner->get_reference_count() > 1 && gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0 |
| 1861 | // The reference count was increased after the managed side was the only one referencing our owner. |
| 1862 | // This means the owner is being referenced again by the unmanaged side, |
| 1863 | // so the owner must hold the managed side alive again to avoid it from being GCed. |
| 1864 | |
| 1865 | // Release the current weak handle and replace it with a strong handle. |
| 1866 | |
| 1867 | GCHandleIntPtr old_gchandle = gchandle.get_intptr(); |
| 1868 | gchandle.handle = { nullptr }; // No longer owns the handle (released by swap function) |
| 1869 | |
| 1870 | GCHandleIntPtr new_gchandle = { nullptr }; |
| 1871 | bool create_weak = false; |
| 1872 | bool target_alive = GDMonoCache::managed_callbacks.ScriptManagerBridge_SwapGCHandleForType( |
| 1873 | old_gchandle, &new_gchandle, create_weak); |
| 1874 | |
| 1875 | if (!target_alive) { |
| 1876 | return; // Called after the managed side was collected, so nothing to do here |
| 1877 | } |
| 1878 | |
| 1879 | gchandle = MonoGCHandleData(new_gchandle, gdmono::GCHandleType::STRONG_HANDLE); |
| 1880 | } |
| 1881 | } |
| 1882 | |
| 1883 | bool CSharpInstance::refcount_decremented() { |
| 1884 | #ifdef DEBUG_ENABLED |
nothing calls this directly
no test coverage detected