some unmmerged changes?

This commit is contained in:
Christian Thaeter 2007-09-19 06:58:54 +02:00
parent aa60abd55e
commit 96b9f65e6f
4 changed files with 60 additions and 184 deletions

View file

@ -23,6 +23,7 @@
#define CINELERRA_LOCKING_H
#include <pthread.h>
#include <errno.h>
#include <nobug.h>
#include "lib/error.h"

View file

@ -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);

View file

@ -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

View file

@ -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;
}