diff options
Diffstat (limited to 'src/driver')
-rw-r--r-- | src/driver/ptyc_driver_ctx.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/src/driver/ptyc_driver_ctx.c b/src/driver/ptyc_driver_ctx.c index cc50e36..78ffb54 100644 --- a/src/driver/ptyc_driver_ctx.c +++ b/src/driver/ptyc_driver_ctx.c @@ -4,7 +4,10 @@ /* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */ /*********************************************************/ +#include <ntcon/ntcon.h> #include <ntapi/ntapi.h> +#include <ntapi/nt_atomic.h> + #include <stdint.h> #include <ptycon/ptycon.h> @@ -20,6 +23,10 @@ /* ntapi accessor table */ const ntapi_vtbl * ptyc_ntapi; +/* ntcon accessor table */ +static ntcon_vtbl ptyc_ntcon_vtbl; +const ntcon_vtbl * const ptyc_ntcon = &ptyc_ntcon_vtbl; + /* package info */ static const struct ptyc_source_version ptyc_src_version = { PTYC_TAG_VER_MAJOR, @@ -35,6 +42,43 @@ struct ptyc_driver_ctx_alloc { const char * units[]; }; +static int32_t ptyc_ntcon_once = 0; + +static int32_t ptyc_ntcon_init(void) +{ + int32_t status; + nt_timeout timeout; + + switch (at_locked_cas_32(&ptyc_ntcon_once,0,1)) { + case 0: + if ((status = ntcon_vtbl_init(&ptyc_ntcon_vtbl))) { + at_locked_add_32(&ptyc_ntcon_once,2); + return status; + } else { + at_locked_inc_32(&ptyc_ntcon_once); + return 0; + } + + case 1: + timeout.quad = -10; + + for (; (at_locked_cas_32(&ptyc_ntcon_once,0,1) == 1); ) + ntapi->zw_delay_execution( + NT_SYNC_ALERTABLE, + &timeout); + + return (ptyc_ntcon_once == 2) + ? 0 : -1; + + case 2: + return 0; + + case 3: + default: + return -1; + } +} + static uint32_t ptyc_argv_flags(uint32_t flags) { uint32_t ret = 0; @@ -122,6 +166,9 @@ int ptyc_get_driver_ctx( if (ptyc_init()) return -1; + if (ptyc_ntcon_init()) + return -1; + options = ptyc_default_options; if (!(meta = argv_get(argv,options,ptyc_argv_flags(flags)))) @@ -172,6 +219,9 @@ int ptyc_create_driver_ctx( if (ptyc_init()) return -1; + if (ptyc_ntcon_init()) + return -1; + if (!(meta = argv_get(argv,ptyc_default_options,0))) return -1; |