12910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/* 22910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * QEMU Object Model. 32910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * 42910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Based on ideas by Avi Kivity <avi@redhat.com> 52910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * 62910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Copyright (C) 2009 Red Hat Inc. 72910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * 82910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Authors: 92910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Luiz Capitulino <lcapitulino@redhat.com> 102910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * 11fd4c0076b7470f5962ff462bae9cd9f208e059b7David Turner * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. 12fd4c0076b7470f5962ff462bae9cd9f208e059b7David Turner * See the COPYING.LIB file in the top-level directory. 132910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * 142910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * QObject Reference Counts Terminology 152910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * ------------------------------------ 162910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * 172910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * - Returning references: A function that returns an object may 182910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * return it as either a weak or a strong reference. If the reference 192910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * is strong, you are responsible for calling QDECREF() on the reference 202910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * when you are done. 212910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * 222910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * If the reference is weak, the owner of the reference may free it at 232910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * any time in the future. Before storing the reference anywhere, you 242910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * should call QINCREF() to make the reference strong. 252910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * 262910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * - Transferring ownership: when you transfer ownership of a reference 272910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * by calling a function, you are no longer responsible for calling 282910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * QDECREF() when the reference is no longer needed. In other words, 292910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * when the function returns you must behave as if the reference to the 302910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * passed object was weak. 312910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */ 322910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#ifndef QOBJECT_H 332910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#define QOBJECT_H 342910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 352910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#include <stddef.h> 362910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#include <assert.h> 372910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 382910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnertypedef enum { 392910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTYPE_NONE, 402910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTYPE_QINT, 412910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTYPE_QSTRING, 422910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTYPE_QDICT, 432910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTYPE_QLIST, 442910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTYPE_QFLOAT, 452910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTYPE_QBOOL, 462910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTYPE_QERROR, 472910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} qtype_code; 482910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 492910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstruct QObject; 502910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 512910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnertypedef struct QType { 522910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qtype_code code; 532910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner void (*destroy)(struct QObject *); 542910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} QType; 552910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 562910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnertypedef struct QObject { 572910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner const QType *type; 582910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner size_t refcnt; 592910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} QObject; 602910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 612910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/* Objects definitions must include this */ 622910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#define QObject_HEAD \ 632910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QObject base 642910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 652910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/* Get the 'base' part of an object */ 662910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#define QOBJECT(obj) (&(obj)->base) 672910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 682910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/* High-level interface for qobject_incref() */ 692910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#define QINCREF(obj) \ 702910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qobject_incref(QOBJECT(obj)) 712910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 722910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/* High-level interface for qobject_decref() */ 732910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#define QDECREF(obj) \ 742910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qobject_decref(QOBJECT(obj)) 752910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 762910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/* Initialize an object to default values */ 772910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#define QOBJECT_INIT(obj, qtype_type) \ 782910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner obj->base.refcnt = 1; \ 792910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner obj->base.type = qtype_type 802910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 812910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/** 822910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qobject_incref(): Increment QObject's reference count 832910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */ 842910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic inline void qobject_incref(QObject *obj) 852910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 862910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (obj) 872910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner obj->refcnt++; 882910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 892910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 902910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/** 912910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qobject_decref(): Decrement QObject's reference count, deallocate 922910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * when it reaches zero 932910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */ 942910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic inline void qobject_decref(QObject *obj) 952910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 962910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (obj && --obj->refcnt == 0) { 972910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner assert(obj->type != NULL); 982910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner assert(obj->type->destroy != NULL); 992910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner obj->type->destroy(obj); 1002910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 1012910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 1022910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1032910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/** 1042910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qobject_type(): Return the QObject's type 1052910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */ 1062910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic inline qtype_code qobject_type(const QObject *obj) 1072910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 1082910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner assert(obj->type != NULL); 1092910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return obj->type->code; 1102910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 1112910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1122910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#endif /* QOBJECT_H */ 113