static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */
#endif
-DECLARE_STACK_OF(CRYPTO_dynlock);
-IMPLEMENT_STACK_OF(CRYPTO_dynlock);
+DECLARE_STACK_OF(CRYPTO_dynlock)
+IMPLEMENT_STACK_OF(CRYPTO_dynlock)
/* real #defines in crypto.h, keep these upto date */
static const char* lock_names[CRYPTO_NUM_LOCKS] =
"dh",
"debug_malloc2",
"dso",
-#if CRYPTO_NUM_LOCKS != 27
+ "dynlock",
+ "engine",
+#if CRYPTO_NUM_LOCKS != 29
# error "Inconsistency between crypto.h and cryptlib.c"
#endif
};
static int (MS_FAR *add_lock_callback)(int *pointer,int amount,
int type,const char *file,int line)=NULL;
static unsigned long (MS_FAR *id_callback)(void)=NULL;
-static CRYPTO_dynlock *(MS_FAR *dynlock_create_callback)(const char *file,
- int line)=NULL;
-static void (MS_FAR *dynlock_locking_callback)(int mode, CRYPTO_dynlock *l,
+static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback)
+ (const char *file,int line)=NULL;
+static void (MS_FAR *dynlock_lock_callback)(int mode,
+ struct CRYPTO_dynlock_value *l, const char *file,int line)=NULL;
+static void (MS_FAR *dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l,
const char *file,int line)=NULL;
-static void (MS_FAR *dynlock_destroy_callback)(CRYPTO_dynlock *l,
- const char *file,int line)=NULL;
-static int (MS_FAR *add_dynlock_callback)(int *pointer,int amount,
- CRYPTO_dynlock *l,const char *file,int line)=NULL;
int CRYPTO_get_new_lockid(char *name)
{
CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK);
return(0);
}
+ CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
if ((dyn_locks == NULL)
- && ((dyn_locks=sk_new_null()) == NULL))
+ && ((dyn_locks=sk_CRYPTO_dynlock_new_null()) == NULL))
{
+ CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
return(0);
}
+ CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
- pointer = dynlock_create_callback(__FILE__,__LINE__);
+ pointer = (CRYPTO_dynlock *)OPENSSL_malloc(sizeof(CRYPTO_dynlock));
if (pointer == NULL)
{
CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
return(0);
}
- i=sk_CRYPTO_dynlock_push(dyn_locks,pointer);
+ pointer->references = 1;
+ pointer->data = dynlock_create_callback(__FILE__,__LINE__);
+ if (pointer->data == NULL)
+ {
+ OPENSSL_free(pointer);
+ CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
+ return(0);
+ }
+
+ CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
+ /* First, try to find an existing empty slot */
+ i=sk_CRYPTO_dynlock_find(dyn_locks,NULL);
+ /* If there was none, push, thereby creating a new one */
+ if (i == -1)
+ i=sk_CRYPTO_dynlock_push(dyn_locks,pointer);
+ CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
+
if (!i)
- dynlock_destroy_callback(pointer,__FILE__,__LINE__);
+ {
+ dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
+ OPENSSL_free(pointer);
+ }
else
i += 1; /* to avoid 0 */
return -i;
void CRYPTO_destroy_dynlockid(int i)
{
+ CRYPTO_dynlock *pointer = NULL;
if (i)
i = -i-1;
- if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks))
- return;
if (dynlock_destroy_callback == NULL)
return;
- dynlock_destroy_callback(sk_CRYPTO_dynlock_value(dyn_locks, i),
- __FILE__,__LINE__);
- sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);
+
+ CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
+
+ if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks))
+ return;
+ pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
+ if (pointer != NULL)
+ {
+ --pointer->references;
+#ifdef REF_CHECK
+ if (pointer->references < 0)
+ {
+ fprintf(stderr,"CRYPTO_destroy_dynlockid, bad reference count\n");
+ abort();
+ }
+ else
+#endif
+ if (--(pointer->references) <= 0)
+ {
+ sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);
+ }
+ else
+ pointer = NULL;
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
+
+ if (pointer)
+ {
+ dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
+ OPENSSL_free(pointer);
+ }
}
-CRYPTO_dynlock *CRYPTO_get_dynlock_value(int i)
+struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i)
{
+ CRYPTO_dynlock *pointer = NULL;
if (i)
i = -i-1;
- if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks))
- return NULL;
- return sk_CRYPTO_dynlock_value(dyn_locks, i);
+
+ CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
+
+ if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
+ pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
+ if (pointer)
+ pointer->references++;
+
+ CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
+
+ if (pointer)
+ return pointer->data;
+ return NULL;
}
-void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file,
- int line)
+struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))
+ (const char *file,int line)
{
- return(locking_callback);
+ return(dynlock_create_callback);
}
-void (*CRYPTO_get_dynlock_lock_callback(void))(int mode,CRYPTO_dynlock *l,
- const char *file,int line)
+void (*CRYPTO_get_dynlock_lock_callback(void))(int mode,
+ struct CRYPTO_dynlock_value *l, const char *file,int line)
{
- return(dynlock_locking_callback);
+ return(dynlock_lock_callback);
}
-int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type,
- const char *file,int line)
+void (*CRYPTO_get_dynlock_destroy_callback(void))
+ (struct CRYPTO_dynlock_value *l, const char *file,int line)
{
- return(add_lock_callback);
+ return(dynlock_destroy_callback);
}
-int (*CRYPTO_get_add_dynlock_callback(void))(int *num,int mount,
- CRYPTO_dynlock *l,
- const char *file,int line)
+void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func)
+ (const char *file, int line))
{
- return(add_dynlock_callback);
+ dynlock_create_callback=func;
}
-void CRYPTO_set_locking_callback(void (*func)(int mode,int type,
- const char *file,int line))
+void CRYPTO_set_dynlock_lock_callback(void (*func)(int mode,
+ struct CRYPTO_dynlock_value *l, const char *file, int line))
{
- locking_callback=func;
+ dynlock_lock_callback=func;
}
-void CRYPTO_set_dynlock_locking_callback(void (*func)(int mode,
- CRYPTO_dynlock *l,
- const char *file,
- int line))
+void CRYPTO_set_dynlock_destroy_callback(void (*func)
+ (struct CRYPTO_dynlock_value *l, const char *file, int line))
{
- dynlock_locking_callback=func;
+ dynlock_destroy_callback=func;
}
-void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type,
+
+void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file,
+ int line)
+ {
+ return(locking_callback);
+ }
+
+int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type,
+ const char *file,int line)
+ {
+ return(add_lock_callback);
+ }
+
+void CRYPTO_set_locking_callback(void (*func)(int mode,int type,
const char *file,int line))
{
- add_lock_callback=func;
+ locking_callback=func;
}
-void CRYPTO_set_add_dynlock_lock_callback(int (*func)(int *num,int mount,
- CRYPTO_dynlock *l,
- const char *file,
- int line))
+void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type,
+ const char *file,int line))
{
- add_dynlock_callback=func;
+ add_lock_callback=func;
}
unsigned long (*CRYPTO_get_id_callback(void))(void)
#endif
if (type < 0)
{
- int i = -type-1;
- if (i < sk_CRYPTO_dynlock_num(dyn_locks))
- dynlock_locking_callback(mode,
- sk_CRYPTO_dynlock_value(dyn_locks,i),
- file,line);
+ int i = -type - 1;
+ struct CRYPTO_dynlock_value *pointer
+ = CRYPTO_get_dynlock_value(i);
+
+ if (pointer)
+ {
+ dynlock_lock_callback(mode, pointer, file, line);
+ }
+
+ CRYPTO_destroy_dynlockid(i);
}
else
if (locking_callback != NULL)
int before= *pointer;
#endif
- if (type < 0)
- {
- int i = -type-1;
- if (i >= sk_CRYPTO_dynlock_num(dyn_locks))
- /* FIXME: This is superbly dangerous if there
- are threads competing on this value, but
- hey, if the user used an invalid lock... */
- ret=(*pointer + amount);
- else
- ret=add_dynlock_callback(pointer,amount,
- sk_CRYPTO_dynlock_value(dyn_locks,i),
- file,line);
- }
- else
- ret=add_lock_callback(pointer,amount,type,file,line);
+ ret=add_lock_callback(pointer,amount,type,file,line);
#ifdef LOCK_DEBUG
fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
CRYPTO_thread_id(),