aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-08-26 10:53:21 -0700
committerAlon Zakai <alonzakai@gmail.com>2013-08-26 10:53:21 -0700
commit70d3a36274858ce8ed071036fb1903e02d606663 (patch)
treea30d0cc44a06f2b2e2548df1ac7187ce21ded173
parentfc56aa8d28bbc5ef66a0a5f21c12892f320098b7 (diff)
parent83504a9c7f58b365b1d580620fe42f6b90191f56 (diff)
Merge pull request #1525 from yukoba/pthread-specific
Bug fixes of pthread specific
-rw-r--r--src/library.js28
-rw-r--r--tests/pthread/specific.c60
-rw-r--r--tests/pthread/specific.c.txt8
-rw-r--r--tests/test_core.py6
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()