Я написал некоторые привязки OCaml для CZMQ на основе руководства http://www.linux-nantes.org/~fmonnier/ocaml/ocaml-wrapping-c.php, которые, похоже, работают очень хорошо. Например, здесь zstr_send:
CAMLprim value
caml_zstr_send(value socket_val, value string_val)
{
CAMLparam2 (socket_val, string_val);
void *sock = CAML_CZMQ_zsocket_val(socket_val);
char *string = String_val(string_val);
int rc = zstr_send(sock, string);
CAMLreturn (Val_int(rc));
}
Я могу отправлять и получать сообщения с использованием этих привязок в большинстве своих кодов. Тем не менее, у меня есть сценарий, где я хотел бы делать отправки и получать внутри обработчика сигнала, до конца выполнения сообщения, передаваемого в фоновом режиме какого-либо другого кода. Возьмем этот упрощенный пример:
open ZMQ
exception SocketBindFailure
let bg_ctx = zctx_new ();;
let pub_sock = zsocket_new bg_ctx ZMQ_PUB;;
let handler _ =
print_endline "enter handler";
print_endline (string_of_int (zstr_send pub_sock "hello"));
print_endline "end handler";
;;
let () =
(try (
(* bind pub socket *)
let rc = zsocket_bind pub_sock "tcp://*:5556" in
if (rc < 0) then ( raise SocketBindFailure );
Sys.set_signal
Sys.sigalrm
(Sys.Signal_handle handler);
ignore
(Unix.setitimer
Unix.ITIMER_REAL
{ Unix.it_interval = 0.01 ; Unix.it_value = 0.01 });
(* do some work *)
)
with
| SocketBindFailure -> raise SocketBindFailure)
;;
Из верхнего уровня это не работает с выходом:
enter handler
0
end handler
Fatal error: exception Sys_blocked_io
C-код, похожий на OCaml выше, работает отлично. Что добавляет OCaml в уравнение, вызывающее это исключение?