once.h revision a438caaf732f7839dc66b4f8dad672527845a003
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * IPRT - Execute Once.
a438caaf732f7839dc66b4f8dad672527845a003vboxsync * Copyright (C) 2006-2012 Oracle Corporation
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * available from http://www.virtualbox.org. This file is free software;
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * you can redistribute it and/or modify it under the terms of the GNU
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * General Public License (GPL) as published by the Free Software
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * The contents of this file may alternatively be used under the terms
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * of the Common Development and Distribution License Version 1.0
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * VirtualBox OSE distribution, in which case the provisions of the
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * CDDL are applicable instead of those of the GPL.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * You may elect to license modified versions of this file under the
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * terms and conditions of either the GPL or the CDDL or both.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/** @defgroup grp_rt_once RTOnce - Execute Once
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * @ingroup grp_rt
a438caaf732f7839dc66b4f8dad672527845a003vboxsync * Callback that gets executed once.
a438caaf732f7839dc66b4f8dad672527845a003vboxsync * @returns IPRT style status code, RTOnce returns this.
a438caaf732f7839dc66b4f8dad672527845a003vboxsync * @param pvUser The user parameter.
a438caaf732f7839dc66b4f8dad672527845a003vboxsynctypedef DECLCALLBACK(int32_t) FNRTONCE(void *pvUser);
a438caaf732f7839dc66b4f8dad672527845a003vboxsync/** Pointer to a FNRTONCE. */
a438caaf732f7839dc66b4f8dad672527845a003vboxsync * Callback that gets executed on IPRT/process termination.
a438caaf732f7839dc66b4f8dad672527845a003vboxsync * @param pvUser The user parameter.
a438caaf732f7839dc66b4f8dad672527845a003vboxsync * @param fLazyCleanUpOk Indicates whether lazy clean-up is OK (see
a438caaf732f7839dc66b4f8dad672527845a003vboxsynctypedef DECLCALLBACK(void) FNRTONCECLEANUP(void *pvUser, bool fLazyCleanUpOk);
a438caaf732f7839dc66b4f8dad672527845a003vboxsync/** Pointer to a FNRTONCE. */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * Execute once structure.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * This is typically a global variable that is statically initialized
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * by RTONCE_INITIALIZER.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsynctypedef struct RTONCE
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync /** Event semaphore that the other guys are blocking on. */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync /** Reference counter for hEventMulti. */
a438caaf732f7839dc66b4f8dad672527845a003vboxsync /** See RTONCESTATE. */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync /** The return code of pfnOnce. */
a438caaf732f7839dc66b4f8dad672527845a003vboxsync /** Pointer to the clean-up function. */
a438caaf732f7839dc66b4f8dad672527845a003vboxsync /** Argument to hand to the clean-up function. */
a438caaf732f7839dc66b4f8dad672527845a003vboxsync /** Clean-up list entry. */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/** Pointer to a execute once struct. */
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * The execute once statemachine.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync /** RTOnce() has not been called.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * Next: NO_SEM */
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync /** RTOnce() is busy, no race.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * Next: CREATING_SEM, DONE */
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync /** More than one RTOnce() caller is busy.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * Next: BUSY_HAVE_SEM, BUSY_SPIN, DONE_CREATING_SEM, DONE */
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync /** More than one RTOnce() caller, the first is busy, the others are
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * Next: DONE */
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync /** More than one RTOnce() caller, the first is busy, the others failed to
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * create a semaphore and are spinning.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * Next: DONE */
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync /** More than one RTOnce() caller, the first has completed, the others
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * are busy creating the semaphore.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * Next: DONE_HAVE_SEM */
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync /** More than one RTOnce() caller, the first is busy grabbing the
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * semaphore, while the others are waiting.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * Next: DONE */
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync /** The execute once stuff has completed. */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/** Static initializer for RTONCE variables. */
a438caaf732f7839dc66b4f8dad672527845a003vboxsync { NIL_RTSEMEVENTMULTI, 0, RTONCESTATE_UNINITIALIZED, VERR_INTERNAL_ERROR, NULL, NULL, { NULL, NULL } }
a438caaf732f7839dc66b4f8dad672527845a003vboxsync * Serializes execution of the pfnOnce function, making sure it's
a438caaf732f7839dc66b4f8dad672527845a003vboxsync * executed exactly once and that nobody returns from RTOnce before
a438caaf732f7839dc66b4f8dad672527845a003vboxsync * it has executed successfully.
a438caaf732f7839dc66b4f8dad672527845a003vboxsync * @returns IPRT like status code returned by pfnOnce.
a438caaf732f7839dc66b4f8dad672527845a003vboxsync * @param pOnce Pointer to the execute once variable.
a438caaf732f7839dc66b4f8dad672527845a003vboxsync * @param pfnOnce The function to executed once.
a438caaf732f7839dc66b4f8dad672527845a003vboxsync * @param pfnCleanUp The function that will be doing the cleaning up.
a438caaf732f7839dc66b4f8dad672527845a003vboxsync * Optional.
a438caaf732f7839dc66b4f8dad672527845a003vboxsync * @param pvUser The user parameter for pfnOnce.
a438caaf732f7839dc66b4f8dad672527845a003vboxsyncRTDECL(int) RTOnceSlow(PRTONCE pOnce, PFNRTONCE pfnOnce, FNRTONCECLEANUP pfnCleanUp, void *pvUser);
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * Serializes execution of the pfnOnce function, making sure it's
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * executed exactly once and that nobody returns from RTOnce before
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * it has executed successfully.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * @returns IPRT like status code returned by pfnOnce.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * @param pOnce Pointer to the execute once variable.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * @param pfnOnce The function to executed once.
a438caaf732f7839dc66b4f8dad672527845a003vboxsync * @param pvUser The user parameter for pfnOnce.
a438caaf732f7839dc66b4f8dad672527845a003vboxsyncDECLINLINE(int) RTOnce(PRTONCE pOnce, PFNRTONCE pfnOnce, void *pvUser)
a438caaf732f7839dc66b4f8dad672527845a003vboxsync int32_t iState = ASMAtomicUoReadS32(&pOnce->iState);
a438caaf732f7839dc66b4f8dad672527845a003vboxsync * Execute pfnOnce once and register a termination clean-up callback.
e420253a89a6e07613f49cfd9a1db9e217039575vboxsync * Serializes execution of the pfnOnce function, making sure it's
e420253a89a6e07613f49cfd9a1db9e217039575vboxsync * executed exactly once and that nobody returns from RTOnce before
e420253a89a6e07613f49cfd9a1db9e217039575vboxsync * it has executed successfully.
e420253a89a6e07613f49cfd9a1db9e217039575vboxsync * @returns IPRT like status code returned by pfnOnce.
e420253a89a6e07613f49cfd9a1db9e217039575vboxsync * @param pOnce Pointer to the execute once variable.
e420253a89a6e07613f49cfd9a1db9e217039575vboxsync * @param pfnOnce The function to executed once.
a438caaf732f7839dc66b4f8dad672527845a003vboxsync * @param pfnCleanUp The function that will be doing the cleaning up.
a438caaf732f7839dc66b4f8dad672527845a003vboxsync * @param pvUser The user parameter for pfnOnce.
a438caaf732f7839dc66b4f8dad672527845a003vboxsyncDECLINLINE(int) RTOnceEx(PRTONCE pOnce, PFNRTONCE pfnOnce, PFNRTONCECLEANUP pfnCleanUp, void *pvUser)
e420253a89a6e07613f49cfd9a1db9e217039575vboxsync int32_t iState = ASMAtomicUoReadS32(&pOnce->iState);
a438caaf732f7839dc66b4f8dad672527845a003vboxsync return RTOnceSlow(pOnce, pfnOnce, pfnCleanUp, pvUser);
6e59cff536e8de93f15fa1fb6b46d0ee01e06829vboxsync * Resets an execute once variable.
6e59cff536e8de93f15fa1fb6b46d0ee01e06829vboxsync * The caller is responsible for making sure there are no concurrent accesses to
6e59cff536e8de93f15fa1fb6b46d0ee01e06829vboxsync * the execute once variable.
6e59cff536e8de93f15fa1fb6b46d0ee01e06829vboxsync * @param pOnce Pointer to the execute once variable.