bio->num_read = 0L;
bio->num_write = 0L;
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
- if (method->create != NULL)
+
+ bio->lock = CRYPTO_THREAD_lock_new();
+ if (bio->lock == NULL) {
+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
+ return 0;
+ }
+
+ if (method->create != NULL) {
if (!method->create(bio)) {
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
- return (0);
+ CRYPTO_THREAD_lock_free(bio->lock);
+ return 0;
}
- return (1);
+ }
+
+ return 1;
}
int BIO_free(BIO *a)
int i;
if (a == NULL)
- return (0);
+ return 0;
+
+ if (CRYPTO_atomic_add(&a->references, -1, &i, a->lock) <= 0)
+ return 0;
- i = CRYPTO_add(&a->references, -1, CRYPTO_LOCK_BIO);
REF_PRINT_COUNT("BIO", a);
if (i > 0)
- return (1);
+ return 1;
REF_ASSERT_ISNT(i < 0);
if ((a->callback != NULL) &&
((i = (int)a->callback(a, BIO_CB_FREE, NULL, 0, 0L, 1L)) <= 0))
- return (i);
+ return i;
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data);
+ CRYPTO_THREAD_lock_free(a->lock);
+
if ((a->method != NULL) && (a->method->destroy != NULL))
a->method->destroy(a);
+
OPENSSL_free(a);
- return (1);
+
+ return 1;
}
void BIO_vfree(BIO *a)
BIO_free(a);
}
+int BIO_up_ref(BIO *a)
+{
+ int i;
+
+ if (CRYPTO_atomic_add(&a->references, 1, &i, a->lock) <= 0)
+ return 0;
+
+ REF_PRINT_COUNT("BIO", a);
+ REF_ASSERT_ISNT(i < 2);
+ return ((i > 1) ? 1 : 0);
+}
+
void BIO_clear_flags(BIO *b, int flags)
{
b->flags &= ~flags;
=head1 NAME
-BIO_new, BIO_set, BIO_free, BIO_vfree, BIO_free_all - BIO allocation and freeing functions
+BIO_new, BIO_set, BIO_up_ref, BIO_free, BIO_vfree, BIO_free_all - BIO allocation and freeing functions
=head1 SYNOPSIS
BIO * BIO_new(BIO_METHOD *type);
int BIO_set(BIO *a,BIO_METHOD *type);
+ int BIO_up_ref(BIO *a);
int BIO_free(BIO *a);
void BIO_vfree(BIO *a);
void BIO_free_all(BIO *a);
BIO_set() sets the method of an already existing BIO.
+BIO_up_ref() increments the reference count associated with the BIO object.
+
BIO_free() frees up a single BIO, BIO_vfree() also frees up a single BIO
but it does not return a value.
If B<a> is NULL nothing is done.
BIO_new() returns a newly created BIO or NULL if the call fails.
-BIO_set(), BIO_free() return 1 for success and 0 for failure.
+BIO_set(), BIO_up_ref() and BIO_free() return 1 for success and 0 for failure.
BIO_free_all() and BIO_vfree() do not return values.
uint64_t num_read;
uint64_t num_write;
CRYPTO_EX_DATA ex_data;
+ CRYPTO_RWLOCK *lock;
};
DEFINE_STACK_OF(BIO)
int BIO_set(BIO *a, BIO_METHOD *type);
int BIO_free(BIO *a);
void BIO_vfree(BIO *a);
+int BIO_up_ref(BIO *a);
int BIO_read(BIO *b, void *data, int len);
int BIO_gets(BIO *bp, char *buf, int size);
int BIO_write(BIO *b, const void *data, int len);
# define CRYPTO_LOCK_RAND 18
# define CRYPTO_LOCK_RAND2 19
# define CRYPTO_LOCK_MALLOC 20
-# define CRYPTO_LOCK_BIO 21
# define CRYPTO_LOCK_READDIR 24
# define CRYPTO_LOCK_RSA_BLINDING 25
# define CRYPTO_LOCK_MALLOC2 27
if (b->next_bio != NULL)
BIO_push(bio, b->next_bio);
b->next_bio = bio;
- CRYPTO_add(&bio->references, 1, CRYPTO_LOCK_BIO);
+ BIO_up_ref(bio);
}
b->init = 1;
break;
case BIO_CTRL_PUSH:
if ((b->next_bio != NULL) && (b->next_bio != ssl->rbio)) {
SSL_set_bio(ssl, b->next_bio, b->next_bio);
- CRYPTO_add(&b->next_bio->references, 1, CRYPTO_LOCK_BIO);
+ BIO_up_ref(b);
}
break;
case BIO_CTRL_POP:
if (ssl->rbio != ssl->wbio)
BIO_free_all(ssl->wbio);
if (b->next_bio != NULL)
- CRYPTO_add(&b->next_bio->references, -1, CRYPTO_LOCK_BIO);
+ BIO_free(b->next_bio);
ssl->wbio = NULL;
ssl->rbio = NULL;
}