Add support for reference counting using C11 atomics

Reviewed-by: Andy Polyakov <appro@openssl.org>
Reviewed-by: Rich Salz <rsalz@openssl.org>

GH: #1500
diff --git a/crypto/engine/eng_int.h b/crypto/engine/eng_int.h
index c604fad..741e687 100644
--- a/crypto/engine/eng_int.h
+++ b/crypto/engine/eng_int.h
@@ -19,6 +19,7 @@
 # include "internal/cryptlib.h"
 # include <internal/engine.h>
 # include <internal/thread_once.h>
+# include "internal/refcount.h"
 
 #ifdef  __cplusplus
 extern "C" {
@@ -156,7 +157,7 @@
     const ENGINE_CMD_DEFN *cmd_defns;
     int flags;
     /* reference count on the structure itself */
-    int struct_ref;
+    CRYPTO_REF_COUNT struct_ref;
     /*
      * reference count on usability of the engine type. NB: This controls the
      * loading and initialisation of any functionality required by this
diff --git a/crypto/engine/eng_lib.c b/crypto/engine/eng_lib.c
index 28de21d..8a21f38 100644
--- a/crypto/engine/eng_lib.c
+++ b/crypto/engine/eng_lib.c
@@ -9,6 +9,7 @@
 
 #include "eng_int.h"
 #include <openssl/rand.h>
+#include "internal/refcount.h"
 
 CRYPTO_RWLOCK *global_engine_lock;
 
@@ -72,10 +73,14 @@
 
     if (e == NULL)
         return 1;
+#ifdef HAVE_ATOMICS
+    CRYPTO_DOWN_REF(&e->struct_ref, &i, global_engine_lock);
+#else
     if (locked)
         CRYPTO_atomic_add(&e->struct_ref, -1, &i, global_engine_lock);
     else
         i = --e->struct_ref;
+#endif
     engine_ref_debug(e, 0, -1)
     if (i > 0)
         return 1;
diff --git a/crypto/engine/eng_list.c b/crypto/engine/eng_list.c
index 934389f..d8eb076 100644
--- a/crypto/engine/eng_list.c
+++ b/crypto/engine/eng_list.c
@@ -349,6 +349,6 @@
         ENGINEerr(ENGINE_F_ENGINE_UP_REF, ERR_R_PASSED_NULL_PARAMETER);
         return 0;
     }
-    CRYPTO_atomic_add(&e->struct_ref, 1, &i, global_engine_lock);
+    CRYPTO_UP_REF(&e->struct_ref, &i, global_engine_lock);
     return 1;
 }