some unmmerged changes?
This commit is contained in:
parent
aa60abd55e
commit
96b9f65e6f
4 changed files with 60 additions and 184 deletions
|
|
@ -23,6 +23,7 @@
|
|||
#define CINELERRA_LOCKING_H
|
||||
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <nobug.h>
|
||||
|
||||
#include "lib/error.h"
|
||||
|
|
|
|||
|
|
@ -78,6 +78,22 @@ cinelerra_mutexacquirer_ensureunlocked (CinelerraMutexacquirer self)
|
|||
cinelerra_mutexacquirer NOBUG_CLEANUP(cinelerra_mutexacquirer_ensureunlocked)
|
||||
|
||||
|
||||
/**
|
||||
* initialize a mutexacquirer state without mutex.
|
||||
* @param self mutexacquirer to be initialized, must be an automatic variable
|
||||
* @return self as given
|
||||
* This initialization is used when cinelerra_mutexacquirer_try_mutex shall be used later
|
||||
*/
|
||||
static inline CinelerraMutexacquirer
|
||||
cinelerra_mutexacquirer_init (CinelerraMutexacquirer self)
|
||||
{
|
||||
REQUIRE (self);
|
||||
self->mutex = NULL;
|
||||
self->state = CINELERRA_UNLOCKED;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize a mutexacquirer state
|
||||
* @param self mutexacquirer to be initialized, must be an automatic variable
|
||||
|
|
@ -87,7 +103,7 @@ cinelerra_mutexacquirer NOBUG_CLEANUP(cinelerra_mutexacquirer_ensureunlocked)
|
|||
* errors are fatal
|
||||
*/
|
||||
static inline CinelerraMutexacquirer
|
||||
cinelerra_mutexacquirer_init (CinelerraMutexacquirer self, CinelerraMutex mutex, enum cinelerra_lockstate state)
|
||||
cinelerra_mutexacquirer_init_mutex (CinelerraMutexacquirer self, CinelerraMutex mutex, enum cinelerra_lockstate state)
|
||||
{
|
||||
REQUIRE (self);
|
||||
REQUIRE (mutex);
|
||||
|
|
@ -100,6 +116,7 @@ cinelerra_mutexacquirer_init (CinelerraMutexacquirer self, CinelerraMutex mutex,
|
|||
return self;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* lock the mutex.
|
||||
* must not already be locked
|
||||
|
|
@ -118,12 +135,51 @@ cinelerra_mutexacquirer_lock (CinelerraMutexacquirer self)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* get the state of a lock.
|
||||
* @param self mutexacquirer associated with a mutex variable
|
||||
* @return CINELERRA_LOCKED when the mutex is locked by this thead
|
||||
*/
|
||||
static inline enum cinelerra_lockstate
|
||||
cinelerra_mutexacquirer_state (CinelerraMutexacquirer self)
|
||||
{
|
||||
REQUIRE (self);
|
||||
return self->state;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* try to lock a mutex.
|
||||
* must not already be locked
|
||||
* @param self mutexacquirer associated with a mutex variable
|
||||
* @param mutex pointer to a mutex which should be tried
|
||||
* @return CINELERRA_LOCKED when the mutex got locked
|
||||
*/
|
||||
static inline enum cinelerra_lockstate
|
||||
cinelerra_mutexacquirer_try_mutex (CinelerraMutexacquirer self, CinelerraMutex mutex)
|
||||
{
|
||||
REQUIRE (self);
|
||||
REQUIRE (self->state == CINELERRA_UNLOCKED, "mutex already locked");
|
||||
|
||||
self->mutex=mutex;
|
||||
switch (pthread_mutex_trylock (&self->mutex->mutex))
|
||||
{
|
||||
case 0:
|
||||
return self->state = CINELERRA_LOCKED;
|
||||
case EBUSY:
|
||||
return CINELERRA_UNLOCKED;
|
||||
default:
|
||||
CINELERRA_DIE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* release mutex.
|
||||
* a mutexacquirer must be unlocked before leaving scope
|
||||
* @param self mutexacquirer associated with a mutex variable
|
||||
*/
|
||||
static inline int
|
||||
static inline void
|
||||
cinelerra_mutexacquirer_unlock (CinelerraMutexacquirer self)
|
||||
{
|
||||
REQUIRE (self);
|
||||
|
|
|
|||
|
|
@ -1,181 +0,0 @@
|
|||
/*
|
||||
smartref.h - smart and weak references
|
||||
|
||||
Copyright (C) CinelerraCV
|
||||
2007, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef CINELERRA_SMARTREF_H
|
||||
#define CINELERRA_SMARTREF_H
|
||||
|
||||
#include <nobug.h>
|
||||
|
||||
typedef struct cinelerra_reftarget_struct cinelerra_reftarget;
|
||||
typedef cinelerra_reftarget* CinelerraReftarget;
|
||||
|
||||
typedef struct cinelerra_reference_struct cinelerra_reference;
|
||||
typedef cinelerra_reference* CinelerraReference;
|
||||
|
||||
#include "lib/mutex.h"
|
||||
#include "lib/llist.h"
|
||||
|
||||
/**
|
||||
* @file Smart and Weak references
|
||||
* Smart references keep some object alive while they exxisting
|
||||
* Weak references become invalidated when the referenced object gets destroyed
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
struct cinelerra_reftarget_struct
|
||||
{
|
||||
void* object;
|
||||
void (*dtor)(void*);
|
||||
cinelerra_mutex lock;
|
||||
llist smartrefs;
|
||||
llist weakrefs;
|
||||
};
|
||||
|
||||
|
||||
CinelerraReftarget
|
||||
cinelerra_reftarget_init (CinelerraReftarget self, void* obj, void (*dtor)(void*))
|
||||
{
|
||||
cinelerra_mutex_init (&self->lock);
|
||||
llist_init (&self->smartrefs);
|
||||
llist_init (&self->weakrefs);
|
||||
self->object = obj;
|
||||
self->dtor = dtor;
|
||||
return self;
|
||||
}
|
||||
|
||||
CinelerraReftarget
|
||||
cinelerra_reftarget_destroy (CinelerraReftarget self)
|
||||
{
|
||||
// lock
|
||||
// check smartrefs empty else error!
|
||||
// invalidate weakrefs
|
||||
// unlock and destroy mutex
|
||||
// if dtor -> call dtor
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
struct cinelerra_reference_struct
|
||||
{
|
||||
cinelerra_mutex lock;
|
||||
CinelerraReftarget target;
|
||||
llist node;
|
||||
};
|
||||
|
||||
/* helper function for nobug */
|
||||
static inline void
|
||||
cinelerra_reference_ensureunlinked (CinelerraReference self)
|
||||
{
|
||||
ENSURE (llist_is_empty (&self->node), "forgot to destroy reference");
|
||||
}
|
||||
|
||||
/* override with a macro to use the cleanup checker */
|
||||
#define cinelerra_reference \
|
||||
cinelerra_reference NOBUG_CLEANUP(cinelerra_reference_ensureunlinked)
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
CinelerraReference
|
||||
cinelerra_smartref_init (CinelerraReference self, CinelerraReftarget target)
|
||||
{
|
||||
cinelerra_mutex_init (&self->lock);
|
||||
llist_init (&self->node);
|
||||
self->target = target;
|
||||
|
||||
cinelerra_mutexacquirer l;
|
||||
cinelerra_mutexacquirer_init_mutex (&l, &target->lock, CINELERRA_LOCKED);
|
||||
llist_insert_tail (&target->smartrefs, &self->node);
|
||||
cinelerra_mutexacquirer_unlock (&l);
|
||||
return self;
|
||||
}
|
||||
|
||||
CinelerraReference
|
||||
cinelerra_smartref_destroy (CinelerraReference self)
|
||||
{
|
||||
cinelerra_mutexacquirer l;
|
||||
cinelerra_mutexacquirer_init_mutex (&l, &self->target->lock, CINELERRA_LOCKED);
|
||||
llist_unlink (&self->node);
|
||||
CinelerraReftarget tmp = self->target;
|
||||
self->target = NULL;
|
||||
cinelerra_mutexacquirer_unlock (&l);
|
||||
|
||||
cinelerra_mutex_destroy (&self->lock);
|
||||
return self;
|
||||
}
|
||||
|
||||
void*
|
||||
cinelerra_smartref_get (CinelerraReference self, CinelerraMutexacquirer lock)
|
||||
{
|
||||
cinelerra_mutexacquirer_init_mutex (lock, &self->lock, CINELERRA_LOCKED);
|
||||
return self->target->object;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
CinelerraReference
|
||||
cinelerra_weakref_init (CinelerraReference self, CinelerraReftarget target)
|
||||
{
|
||||
cinelerra_mutex_init (&self->lock);
|
||||
llist_init (&self->node);
|
||||
self->target = target;
|
||||
|
||||
cinelerra_mutexacquirer l;
|
||||
cinelerra_mutexacquirer_init_mutex (&l, &target->lock, CINELERRA_LOCKED);
|
||||
llist_insert_tail (&target->weakrefs, &self->node);
|
||||
cinelerra_mutexacquirer_unlock (&l);
|
||||
return self;
|
||||
}
|
||||
|
||||
CinelerraReference
|
||||
cinelerra_weakref_destroy (CinelerraReference self)
|
||||
{
|
||||
//cinelerra_mutexacquirer l;
|
||||
//cinelerra_mutexacquirer_init_mutex (&l, &self->target->lock, CINELERRA_LOCKED);
|
||||
//llist_unlink (&self->node);
|
||||
//self->target = NULL;
|
||||
//cinelerra_mutexacquirer_unlock (&l);
|
||||
|
||||
//cinelerra_mutex_destroy (&self->lock);
|
||||
return self;
|
||||
}
|
||||
|
||||
void*
|
||||
cinelerra_weakref_get (CinelerraReference self, CinelerraMutexacquirer lock)
|
||||
{
|
||||
cinelerra_mutexacquirer_init_mutex (lock, &self->lock, CINELERRA_LOCKED);
|
||||
return self->target? self->target->object : NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -27,6 +27,6 @@ int mutexforgotunlock()
|
|||
cinelerra_mutex_init (&m);
|
||||
|
||||
cinelerra_mutexacquirer l;
|
||||
cinelerra_mutexacquirer_init (&l, &m, CINELERRA_LOCKED);
|
||||
cinelerra_mutexacquirer_init_mutex (&l, &m, CINELERRA_LOCKED);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue