/* * CDE - Common Desktop Environment * * Copyright (c) 1993-2012, The Open Group. All rights reserved. * * These libraries and programs are free software; you can * redistribute them and/or modify them under the terms of the GNU * Lesser General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * These libraries and programs are distributed in the hope that * they will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public * License along with these libraries and programs; if not, write * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth * Floor, Boston, MA 02110-1301 USA */ /* $XConsortium: ilobject.c /main/3 1995/10/23 15:58:21 rswiston $ */ /**--------------------------------------------------------------------- *** *** (c)Copyright 1991 Hewlett-Packard Co. *** *** RESTRICTED RIGHTS LEGEND *** Use, duplication, or disclosure by the U.S. Government is subject to *** restrictions as set forth in sub-paragraph (c)(1)(ii) of the Rights in *** Technical Data and Computer Software clause in DFARS 252.227-7013. *** Hewlett-Packard Company *** 3000 Hanover Street *** Palo Alto, CA 94304 U.S.A. *** Rights for non-DOD U.S. Government Departments and Agencies are as set *** forth in FAR 52.227-19(c)(1,2). *** ***-------------------------------------------------------------------*/ /* /ilc/ilobject.c : General object handling code, e.g. ilDestroyObject(). */ #include #include "ilint.h" #include "ilcontext.h" #include "ilerrors.h" /* ------------------------ ilCreateObject ----------------------------------- */ /* Creates an object of size "sizeInBytes" and returns a ptr to it, or null if failure (the error code in "context" is set in either case). The object is added to the given "context". "sizeInBytes" must be a minimum of "sizeof(ilObjectRec)". The function "Destroy" will be called by ilDestroyObject(), as: Destroy (ilObjectPtr pObject); Before destroying this object. The Destroy() function must free any object-specific data etc. It MUST not touch the fields in the object header (ilObjectRec) or free *pObject. */ IL_PRIVATE ilObjectPtr _ilCreateObject ( ilContext context, /* context to add object to */ int objectType, /* code for object, e.g. IL_PIPE */ void (*Destroy)(), /* destroy function; see above */ /* Use portable type, bug report OSF_QAR#32082 */ size_t sizeInBytes /* size of object to create */ ) { ilContextPtr pContext; ilObjectPtr pObject; /* Allocate object rec, return if failure. */ pContext = (ilContextPtr)context; pObject = (ilObjectPtr)IL_MALLOC (sizeInBytes); if (!pObject) { pContext->p.error = IL_ERROR_MALLOC; return (ilObjectPtr)NULL; } /* Fill in object header, init refCount to 1 => no one attached to it yet. */ pObject->p.context = (ilContext)pContext; pObject->p.objectType = objectType; pObject->p.pPrivate = (ilPtr)NULL; pObject->Destroy = Destroy; pObject->refCount = 1; /* Add the object to the front of the list of objects. */ pObject->pNext = pContext->objectHead.pNext; pObject->pPrev = (ilPtr)&pContext->objectHead; ((ilObjectPtr)pContext->objectHead.pNext)->pPrev = (ilPtr)pObject; pContext->objectHead.pNext = (ilPtr)pObject; pContext->p.error = IL_OK; return pObject; } /* ------------------------ ilDestroyObject -------------------------------- */ /* Public function: see spec. */ ilBool ilDestroyObject ( ilObject object ) { ilObjectPtr pObject; /* Downcount refCount, exit if not zero - object is still attached to others. Call object-specific destroy function, free client private if present, remove object from the linked list, free the object. */ pObject = (ilObjectPtr)object; if ((pObject->p.objectType == IL_NULL_OBJECT) || (pObject->p.objectType > IL_MAX_OBJECT_TYPE)) { pObject->p.context->error = IL_ERROR_OBJECT_TYPE; return FALSE; } pObject->p.context->error = 0; if (--pObject->refCount > 0) return TRUE; /* object still attached; EXIT */ (*pObject->Destroy) (pObject); if (pObject->p.pPrivate) free (pObject->p.pPrivate); /* note: caller used malloc, not IL_MALLOC() */ ((ilObjectPtr)pObject->pPrev)->pNext = (ilPtr)pObject->pNext; ((ilObjectPtr)pObject->pNext)->pPrev = (ilPtr)pObject->pPrev; IL_FREE (pObject); return TRUE; } /* ------------------------ ilObjectInitContext ------------------------- */ /* Called by ilCreateContext() to create object data in the given context. Returns: true if add was ok, else error: caller should free all. */ IL_PRIVATE ilBool _ilObjectInitContext ( ilContextPtr pContext ) { /* pCOD->head points to the list of objects; init list to null (point to self). */ pContext->objectHead.p.context = (ilContext)pContext; pContext->objectHead.pPrev = pContext->objectHead.pNext = (ilPtr)&pContext->objectHead; return TRUE; } /* ------------------------ ilObjectDestroyContext ------------------------- */ /* Called by ilDestroyContext() to destroy object data in the given context. */ IL_PRIVATE void _ilObjectDestroyContext ( ilContextPtr pContext ) { ilObjectPtr pObject, pNextObject, pObjectHead; /* Loop thru and destroy all objects until list points back to head (done). */ pObjectHead = &pContext->objectHead; pObject = (ilObjectPtr)pObjectHead->pNext; while (pObject != pObjectHead) { pNextObject = (ilObjectPtr)pObject->pNext; ilDestroyObject ((ilObject)pObject); pObject = pNextObject; } }