[cl-plus-ssl-cvs] CVS cl+ssl

dlichteblau dlichteblau at common-lisp.net
Sun Apr 3 13:20:29 UTC 2011


Update of /project/cl-plus-ssl/cvsroot/cl+ssl
In directory cl-net:/tmp/cvs-serv31882

Modified Files:
	cl+ssl.asd ffi.lisp 
Log Message:
Implement locking and thread ID callbacks using bxthreads; lock around initialization


--- /project/cl-plus-ssl/cvsroot/cl+ssl/cl+ssl.asd	2008/03/07 21:26:48	1.6
+++ /project/cl-plus-ssl/cvsroot/cl+ssl/cl+ssl.asd	2011/04/03 13:20:29	1.7
@@ -13,7 +13,8 @@
 (in-package :cl+ssl-system)
 
 (defsystem :cl+ssl
-  :depends-on (:cffi :trivial-gray-streams :flexi-streams #+sbcl :sb-posix)
+  :depends-on (:cffi :trivial-gray-streams :flexi-streams #+sbcl :sb-posix
+		     :bordeaux-threads :trivial-garbage)
   :serial t
   :components
    ((:file "package")
--- /project/cl-plus-ssl/cvsroot/cl+ssl/ffi.lisp	2010/05/23 23:24:38	1.14
+++ /project/cl-plus-ssl/cvsroot/cl+ssl/ffi.lisp	2011/04/03 13:20:29	1.15
@@ -205,6 +205,14 @@
   (ctx ssl-ctx)
   (pem_passwd_cb :pointer))
 
+(cffi:defcfun ("CRYPTO_num_locks" crypto-num-locks) :int)
+(cffi:defcfun ("CRYPTO_set_locking_callback" crypto-set-locking-callback)
+    :void
+  (fun :pointer))
+(cffi:defcfun ("CRYPTO_set_id_callback" crypto-set-id-callback)
+    :void
+  (fun :pointer))
+
 ;;; Funcall wrapper
 ;;;
 (defvar *socket*)
@@ -369,7 +377,54 @@
 (defun ssl-ctx-set-session-cache-mode (ctx mode)
   (ssl-ctx-ctrl ctx +SSL_CTRL_SET_SESS_CACHE_MODE+ mode 0))
 
+(defvar *locks*)
+(defconstant +CRYPTO-LOCK+ 1)
+(defconstant +CRYPTO-UNLOCK+ 2)
+(defconstant +CRYPTO-READ+ 4)
+(defconstant +CRYPTO-WRITE+ 8)
+
+;; zzz as of early 2011, bxthreads is totally broken on SBCL wrt. explicit
+;; locking of recursive locks.  with-recursive-lock works, but acquire/release
+;; don't.  Hence we use non-recursize locks here (but can use a recursive
+;; lock for the global lock).
+
+(cffi:defcallback locking-callback :void
+    ((mode :int)
+     (n :int)
+     (file :string)
+     (line :int))
+  (declare (ignore file line))
+  ;; (assert (logtest mode (logior +CRYPTO-READ+ +CRYPTO-WRITE+)))
+  (let ((lock (elt *locks* n)))
+    (cond
+      ((logtest mode +CRYPTO-LOCK+)
+       (bt:acquire-lock lock))
+      ((logtest mode +CRYPTO-UNLOCK+)
+       (bt:release-lock lock))
+      (t
+       (error "fell through")))))
+
+(defvar *threads* (trivial-garbage:make-weak-hash-table :weakness :key))
+(defvar *thread-counter* 0)
+
+(defparameter *global-lock*
+  (bordeaux-threads:make-recursive-lock "SSL initialization"))
+
+;; zzz BUG: On a 32-bit system and under non-trivial load, this counter
+;; is likely to wrap in less than a year.
+(cffi:defcallback threadid-callback :unsigned-long ()
+  (bordeaux-threads:with-recursive-lock-held (*global-lock*)
+    (let ((self (bt:current-thread)))
+      (or (gethash self *threads*)
+	  (setf (gethash self *threads*)
+		(incf *thread-counter*))))))
+
 (defun initialize (&key (method 'ssl-v23-method) rand-seed)
+  (setf *locks* (loop
+		   repeat (crypto-num-locks)
+		   collect (bt:make-lock)))
+  (crypto-set-locking-callback (cffi:callback locking-callback))
+  (crypto-set-id-callback (cffi:callback threadid-callback))
   (setf *bio-lisp-method* (make-bio-lisp-method))
   (ssl-load-error-strings)
   (ssl-library-init)
@@ -398,10 +453,11 @@
 
 Hint: do not use Common Lisp RANDOM function to generate the RAND-SEED, 
 because the function usually returns predictable values."
-  (unless (ssl-initialized-p)
-    (initialize :method method :rand-seed rand-seed))
-  (unless *bio-lisp-method*
-    (setf *bio-lisp-method* (make-bio-lisp-method))))
+  (bordeaux-threads:with-recursive-lock-held (*global-lock*)
+    (unless (ssl-initialized-p)
+      (initialize :method method :rand-seed rand-seed))
+    (unless *bio-lisp-method*
+      (setf *bio-lisp-method* (make-bio-lisp-method)))))
 
 (defun use-certificate-chain-file (certificate-chain-file)
   "Loads a PEM encoded certificate chain file CERTIFICATE-CHAIN-FILE





More information about the cl-plus-ssl-cvs mailing list