Permalink
Browse files

Wrap all PKCS#11 calls by rb_thread_blocking_region() for Ruby 1.9.

This makes it more usable in multithreaded applications.
  • Loading branch information...
1 parent 75d113d commit 16cf2259b3b4e02e72c31896fc7c6afd38703299 @larskanis committed Oct 8, 2010
Showing with 179 additions and 53 deletions.
  1. +12 −1 Rakefile
  2. +1 −0 ext/extconf.rb
  3. +72 −0 ext/generate_thread_funcs.rb
  4. +71 −52 ext/pk11.c
  5. +3 −0 ext/pk11.h
  6. +20 −0 test/test_pkcs11_crypt.rb
View
@@ -8,6 +8,8 @@ require 'rake/extensiontask'
CLEAN.include 'ext/pk11_struct_def.inc'
CLEAN.include 'ext/pk11_struct_impl.inc'
CLEAN.include 'ext/pk11_const_def.inc'
+CLEAN.include 'ext/pk11_thread_funcs.h'
+CLEAN.include 'ext/pk11_thread_funcs.c'
CLEAN.include 'lib/pkcs11_ext.so'
CLEAN.include 'tmp'
@@ -26,6 +28,9 @@ hoe = Hoe.spec 'pkcs11' do
spec_extras[:files] = File.read_utf("Manifest.txt").split(/\r?\n\r?/)
spec_extras[:files] << 'ext/pk11_struct_impl.inc'
spec_extras[:files] << 'ext/pk11_struct_def.inc'
+ spec_extras[:files] << 'ext/pk11_const_def.inc'
+ spec_extras[:files] << 'ext/pk11_thread_funcs.h'
+ spec_extras[:files] << 'ext/pk11_thread_funcs.c'
end
ENV['RUBY_CC_VERSION'] = '1.8.6:1.9.1'
@@ -36,14 +41,20 @@ Rake::ExtensionTask.new('pkcs11_ext', hoe.spec) do |ext|
ext.cross_platform = ['i386-mswin32', 'i386-mingw32'] # forces the Windows platform instead of the default one
end
-file 'ext/extconf.rb' => 'ext/pk11_struct_def.inc'
+file 'ext/extconf.rb' => ['ext/pk11_struct_def.inc', 'ext/pk11_thread_funcs.c']
file 'ext/pk11_struct_def.inc' => 'ext/generate_structs.rb' do
sh "ruby ext/generate_structs.rb --def ext/pk11_struct_def.inc --impl ext/pk11_struct_impl.inc --const ext/pk11_const_def.inc ext/include/pkcs11t.h"
end
file 'ext/pk11_struct_impl.inc' => 'ext/pk11_struct_def.inc'
file 'ext/pk11.c' => 'ext/pk11_struct_def.inc'
file 'ext/pk11_const.c' => 'ext/pk11_struct_def.inc'
+file 'ext/pk11_thread_funcs.h' => 'ext/generate_thread_funcs.rb' do
+ sh "ruby ext/generate_thread_funcs.rb --impl ext/pk11_thread_funcs.c --decl ext/pk11_thread_funcs.h ext/include/pkcs11f.h"
+end
+file 'ext/pk11_thread_funcs.c' => 'ext/pk11_thread_funcs.h'
+file 'ext/pk11.h' => 'ext/pk11_thread_funcs.h'
+
# RDoc-upload task for github (currently on rubyforge)
#
# require 'grancher/task'
View
@@ -3,4 +3,5 @@
basedir = File.dirname(__FILE__)
$CPPFLAGS += " -I \"#{basedir}/include\""
have_func("rb_str_set_len")
+have_func("rb_thread_blocking_region")
create_makefile("pkcs11_ext");
@@ -0,0 +1,72 @@
+#!/usr/bin/env ruby
+# This quick and dirty parser for PKCS#11 functions generates
+# wrapper functions for using rb_thread_blocking_region()
+# of Ruby 1.9.
+
+require 'optparse'
+
+options = Struct.new(:verbose, :impl, :decl).new
+OptionParser.new do |opts|
+ opts.banner = "Usage: #{$0} [options] <header-file.h>*"
+
+ opts.on("-v", "--[no-]verbose", "Run verbosely", &options.method(:verbose=))
+ opts.on("--decl FILE", "Write declarations to this file", &options.method(:decl=))
+ opts.on("--impl FILE", "Write implementations to this file", &options.method(:impl=))
+ opts.on_tail("-h", "--help", "Show this message") do
+ puts opts
+ exit
+ end
+end.parse!
+
+Attribute = Struct.new(:type, :name)
+
+File.open(options.decl, "w") do |fd_decl|
+File.open(options.impl, "w") do |fd_impl|
+fd_decl.puts <<-EOT
+ #ifndef #{options.decl.gsub(/[^\w]/, "_").upcase}
+ #define #{options.decl.gsub(/[^\w]/, "_").upcase}
+ #include "pk11.h"
+ #ifdef HAVE_RB_THREAD_BLOCKING_REGION
+EOT
+fd_impl.puts <<-EOT
+ #include #{File.basename(options.decl).inspect}
+ #ifdef HAVE_RB_THREAD_BLOCKING_REGION
+EOT
+ARGV.each do |file_h|
+ c_src = IO.read(file_h)
+ c_src.scan(/CK_PKCS11_FUNCTION_INFO\((.+?)\).*?\((.*?)\);/m) do
+ func_name, func_param_list = $1, $2
+ func_params = []
+ func_param_list.scan(/^\s+([A-Z_0-9]+)\s+([\w_]+)/) do |elem|
+ func_params << Attribute.new($1, $2)
+ end
+ puts "func_name:#{func_name.inspect} func_params: #{func_params.inspect}" if options.verbose
+
+ fd_decl.puts <<-EOT
+ struct tbr_#{func_name}_params {
+ CK_#{func_name} func;
+ struct { #{ func_params.map{|f| f.type+" "+f.name+";"} } } params;
+ CK_RV retval;
+ };
+ VALUE tbf_#{func_name}( void *data );
+
+ EOT
+ fd_impl.puts <<-EOT
+ VALUE tbf_#{func_name}( void *data ){
+ struct tbr_#{func_name}_params *p = (struct tbr_#{func_name}_params*)data;
+ p->retval = p->func( #{func_params.map{|f| "p->params."+f.name}.join(",") } );
+ return Qnil;
+ }
+
+ EOT
+ end
+end
+fd_impl.puts <<-EOT
+ #endif
+EOT
+fd_decl.puts <<-EOT
+ #endif
+ #endif
+EOT
+end
+end
Oops, something went wrong.

0 comments on commit 16cf225

Please sign in to comment.