diff options
author | Alon Zakai <alonzakai@gmail.com> | 2013-08-26 10:53:21 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2013-08-26 10:53:21 -0700 |
commit | 70d3a36274858ce8ed071036fb1903e02d606663 (patch) | |
tree | a30d0cc44a06f2b2e2548df1ac7187ce21ded173 | |
parent | fc56aa8d28bbc5ef66a0a5f21c12892f320098b7 (diff) | |
parent | 83504a9c7f58b365b1d580620fe42f6b90191f56 (diff) |
Merge pull request #1525 from yukoba/pthread-specific
Bug fixes of pthread specific
-rw-r--r-- | src/library.js | 28 | ||||
-rw-r--r-- | tests/pthread/specific.c | 60 | ||||
-rw-r--r-- | tests/pthread/specific.c.txt | 8 | ||||
-rw-r--r-- | tests/test_core.py | 6 |
4 files changed, 95 insertions, 7 deletions
diff --git a/src/library.js b/src/library.js index 9e78db13..3ba2f56b 100644 --- a/src/library.js +++ b/src/library.js @@ -6808,24 +6808,38 @@ LibraryManager.library = { _pthread_once.seen[ptr] = 1; }, + $PTHREAD_SPECIFIC: {}, + $PTHREAD_SPECIFIC_NEXT_KEY: 1, + pthread_key_create__deps: ['$PTHREAD_SPECIFIC', '$PTHREAD_SPECIFIC_NEXT_KEY', '$ERRNO_CODES'], pthread_key_create: function(key, destructor) { - if (!_pthread_key_create.keys) _pthread_key_create.keys = {}; + if (key == 0) { + return ERRNO_CODES.EINVAL; + } + {{{ makeSetValue('key', '0', 'PTHREAD_SPECIFIC_NEXT_KEY', 'i32*') }}} // values start at 0 - _pthread_key_create.keys[key] = 0; + PTHREAD_SPECIFIC[PTHREAD_SPECIFIC_NEXT_KEY] = 0; + PTHREAD_SPECIFIC_NEXT_KEY++; + return 0; }, + pthread_getspecific__deps: ['$PTHREAD_SPECIFIC'], pthread_getspecific: function(key) { - return _pthread_key_create.keys[key] || 0; + return PTHREAD_SPECIFIC[key] || 0; }, + pthread_setspecific__deps: ['$PTHREAD_SPECIFIC', '$ERRNO_CODES'], pthread_setspecific: function(key, value) { - _pthread_key_create.keys[key] = value; + if (value == 0) { + return ERRNO_CODES.EINVAL; + } + PTHREAD_SPECIFIC[key] = value; + return 0; }, - pthread_key_delete: ['$ERRNO_CODES'], + pthread_key_delete__deps: ['$PTHREAD_SPECIFIC', '$ERRNO_CODES'], pthread_key_delete: function(key) { - if (_pthread_key_create.keys[key]) { - delete _pthread_key_create.keys[key]; + if (key in PTHREAD_SPECIFIC) { + delete PTHREAD_SPECIFIC[key]; return 0; } return ERRNO_CODES.EINVAL; diff --git a/tests/pthread/specific.c b/tests/pthread/specific.c new file mode 100644 index 00000000..914884e7 --- /dev/null +++ b/tests/pthread/specific.c @@ -0,0 +1,60 @@ +#include <stdio.h> +#include <assert.h> +#include <errno.h> +#include <pthread.h> + +static void destr_function(void *arg) +{ + // Not implemented yet in Emscripten +} + +int main(void) +{ + pthread_key_t key = 0; + int rv; + int data = 123; + int *data2; + + assert(pthread_key_delete(key) != 0); + assert(pthread_getspecific(key) == NULL); + + rv = pthread_key_create(&key, &destr_function); + printf("pthread_key_create = %d\n", rv); + assert(rv == 0); + + assert(pthread_getspecific(key) == NULL); + + rv = pthread_setspecific(key, (void*) &data); + printf("pthread_setspecific = %d\n", rv); + assert(rv == 0); + + data2 = pthread_getspecific(key); + assert(data2 != NULL); + printf("pthread_getspecific = %d\n", *data2); + assert(*data2 == 123); + + rv = pthread_key_create(&key, &destr_function); + data2 = pthread_getspecific(key); + printf("pthread_getspecific after key recreate = %p\n", data2); + assert(data2 == NULL); + + rv = pthread_key_delete(key); + printf("pthread_key_delete = %d\n", rv); + assert(rv == 0); + + rv = pthread_key_delete(key); + printf("pthread_key_delete repeated = %d\n", rv); + assert(rv == EINVAL); + + rv = pthread_setspecific(key, NULL); + printf("pthread_setspecific for value NULL = %d\n", rv); + assert(rv == EINVAL); + + rv = pthread_key_create(&key, &destr_function); + assert(rv == 0); + rv = pthread_key_delete(key); + printf("pthread_key_delete just after created = %d\n", rv); + assert(rv == 0); + + return 0; +} diff --git a/tests/pthread/specific.c.txt b/tests/pthread/specific.c.txt new file mode 100644 index 00000000..ad122b3d --- /dev/null +++ b/tests/pthread/specific.c.txt @@ -0,0 +1,8 @@ +pthread_key_create = 0 +pthread_setspecific = 0 +pthread_getspecific = 123 +pthread_getspecific after key recreate = (nil) +pthread_key_delete = 0 +pthread_key_delete repeated = 22 +pthread_setspecific for value NULL = 22 +pthread_key_delete just after created = 0 diff --git a/tests/test_core.py b/tests/test_core.py index 7eff0d2f..7c5b651f 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -4664,6 +4664,12 @@ The current type of b is: 9 ''' self.do_run(src, 'BA') + def test_pthread_specific(self): + if self.emcc_args is None: return self.skip('requires emcc') + src = open(path_from_root('tests', 'pthread', 'specific.c'), 'r').read() + expected = open(path_from_root('tests', 'pthread', 'specific.c.txt'), 'r').read() + self.do_run(src, expected, force_c=True) + def test_time(self): # XXX Not sure what the right output is here. Looks like the test started failing with daylight savings changes. Modified it to pass again. src = open(path_from_root('tests', 'time', 'src.c'), 'r').read() |