Пример #1
0
DISPATCH_NOINLINE
_os_object_t
_os_object_retain(_os_object_t obj)
{
	int xref_cnt = _os_object_xrefcnt_inc(obj);
	if (slowpath(xref_cnt <= 0)) {
		_OS_OBJECT_CLIENT_CRASH("Resurrection of an object");
	}
	return obj;
}
Пример #2
0
bool
_os_object_allows_weak_reference(_os_object_t obj)
{
	int xref_cnt = obj->os_obj_xref_cnt;
	if (slowpath(xref_cnt == -1)) {
		return false;
	}
	if (slowpath(xref_cnt < -1)) {
		_OS_OBJECT_CLIENT_CRASH("Over-release of an object");
	}
	return true;
}
Пример #3
0
DISPATCH_NOINLINE
void
_os_object_release(_os_object_t obj)
{
	int xref_cnt = _os_object_xrefcnt_dec(obj);
	if (fastpath(xref_cnt >= 0)) {
		return;
	}
	if (slowpath(xref_cnt < -1)) {
		_OS_OBJECT_CLIENT_CRASH("Over-release of an object");
	}
	return _os_object_xref_dispose(obj);
}
Пример #4
0
DISPATCH_NOINLINE
_os_object_t
_os_object_retain_with_resurrect(_os_object_t obj)
{
	int xref_cnt = _os_object_xrefcnt_inc(obj);
	if (slowpath(xref_cnt < 0)) {
		_OS_OBJECT_CLIENT_CRASH("Resurrection of an overreleased object");
	}
	if (slowpath(xref_cnt == 0)) {
		_os_object_retain_internal(obj);
	}
	return obj;
}
Пример #5
0
DISPATCH_NOINLINE
_os_object_t
_os_object_retain(_os_object_t obj)
{
	int xref_cnt = obj->os_obj_xref_cnt;
	if (slowpath(xref_cnt == _OS_OBJECT_GLOBAL_REFCNT)) {
		return obj; // global object
	}
	xref_cnt = dispatch_atomic_inc2o(obj, os_obj_xref_cnt, relaxed);
	if (slowpath(xref_cnt <= 0)) {
		_OS_OBJECT_CLIENT_CRASH("Resurrection of an object");
	}
	return obj;
}
Пример #6
0
DISPATCH_NOINLINE
void
_os_object_release(_os_object_t obj)
{
	int xref_cnt = obj->os_obj_xref_cnt;
	if (slowpath(xref_cnt == _OS_OBJECT_GLOBAL_REFCNT)) {
		return; // global object
	}
	xref_cnt = dispatch_atomic_dec2o(obj, os_obj_xref_cnt, relaxed);
	if (fastpath(xref_cnt >= 0)) {
		return;
	}
	if (slowpath(xref_cnt < -1)) {
		_OS_OBJECT_CLIENT_CRASH("Over-release of an object");
	}
	return _os_object_xref_dispose(obj);
}
Пример #7
0
bool
_os_object_retain_weak(_os_object_t obj)
{
	int xref_cnt = obj->os_obj_xref_cnt;
	if (slowpath(xref_cnt == _OS_OBJECT_GLOBAL_REFCNT)) {
		return true; // global object
	}
retry:
	if (slowpath(xref_cnt == -1)) {
		return false;
	}
	if (slowpath(xref_cnt < -1)) {
		goto overrelease;
	}
	if (slowpath(!dispatch_atomic_cmpxchgvw2o(obj, os_obj_xref_cnt, xref_cnt,
			xref_cnt + 1, &xref_cnt, relaxed))) {
		goto retry;
	}
	return true;
overrelease:
	_OS_OBJECT_CLIENT_CRASH("Over-release of an object");
}
Пример #8
0
static voucher_t
_voucher_find_and_retain(mach_voucher_t kv)
{
	voucher_t v;
	if (!kv) return NULL;
	_vouchers_lock_lock();
	TAILQ_FOREACH(v, _vouchers_head(kv), v_list) {
		if (v->v_ipc_kvoucher == kv) {
			int xref_cnt = os_atomic_inc2o(v, os_obj_xref_cnt, relaxed);
			_dispatch_voucher_debug("retain  -> %d", v, xref_cnt + 1);
			if (slowpath(xref_cnt < 0)) {
				_dispatch_voucher_debug("over-release", v);
				_OS_OBJECT_CLIENT_CRASH("Voucher over-release");
			}
			if (xref_cnt == 0) {
				// resurrection: raced with _voucher_remove
				(void)os_atomic_inc2o(v, os_obj_ref_cnt, relaxed);
			}
			break;
		}
	}
	_vouchers_lock_unlock();
	return v;
}