summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog26
-rw-r--r--PROGRESS6
-rw-r--r--attr.c30
-rw-r--r--implement.h34
-rw-r--r--private.c10
-rw-r--r--pthread.h54
-rw-r--r--sync.c42
7 files changed, 127 insertions, 75 deletions
diff --git a/ChangeLog b/ChangeLog
index 14d1151..597820c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+Fri Jul 24 03:00:25 1998 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * attr.c (pthread_attr_destroy): Fix merge conflicts.
+ (pthread_attr_getdetachstate): Fix merge conflicts.
+ (pthread_attr_setdetachstate): Fix merge conflicts.
+
+ * pthread.h: Fix merge conflicts.
+
+ * sync.c (pthread_join): Fix merge conflicts.
+
+Fri Jul 24 00:21:21 1998 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * sync.c (pthread_join): Add check for valid and joinable
+ thread.
+ (pthread_detach): Implement. After checking for a valid and joinable
+ thread, it's still a no-op.
+
+ * private.c (_pthread_find_thread_entry): Bug prevented returning
+ an error value in some cases.
+
+ * attr.c (pthread_attr_setdetachedstate): Implement.
+ (pthread_attr_getdetachedstate): Implement.
+
+ * implement.h: Move more hidden definitions into here from
+ pthread.h.
+
1998-07-24 Ben Elliston <bje@cygnus.com>
* pthread.h (PTHREAD_CREATE_JOINABLE): Define.
diff --git a/PROGRESS b/PROGRESS
index 1613459..81ac529 100644
--- a/PROGRESS
+++ b/PROGRESS
@@ -1,4 +1,4 @@
-Last updated: $Date: 1998/07/23 16:00:12 $
+Last updated: $Date: 1998/07/23 17:12:12 $
Completion: 54 out of 61 functions [ 88%]
@@ -38,7 +38,7 @@ no. name status
29 pthread_cond_timedwait *
30 pthread_cond_wait *
31 pthread_create *
-32 pthread_detach
+32 pthread_detach *
33 pthread_equal *
34 pthread_exit *
35 pthread_getschedparam *
@@ -66,5 +66,5 @@ no. name status
57 pthread_setcanceltype *
58 pthread_setschedparam *
59 pthread_setspecific *
-60 pthread_sigmask
+60 pthread_sigmask
61 pthread_testcancel
diff --git a/attr.c b/attr.c
index 0e72575..22332c0 100644
--- a/attr.c
+++ b/attr.c
@@ -11,7 +11,7 @@
static int
is_attr(pthread_attr_t *attr)
{
- /* Return 0 if the attr object is valid, 1 otherwise. */
+ /* Return 0 if the attr object is valid, non-zero otherwise. */
return (attr == NULL || attr->valid != _PTHREAD_ATTR_VALID);
}
@@ -107,6 +107,20 @@ pthread_attr_init(pthread_attr_t *attr)
}
int
+pthread_attr_destroy(pthread_attr_t *attr)
+{
+ if (is_attr(attr) != 0)
+ {
+ return EINVAL;
+ }
+
+ /* Set the attribute object to a specific invalid value. */
+ attr->valid = _PTHREAD_ATTR_INVALID;
+
+ return 0;
+}
+
+int
pthread_attr_getdetachstate(const pthread_attr_t *attr,
int *detachstate)
{
@@ -137,17 +151,3 @@ pthread_attr_setdetachstate(pthread_attr_t *attr,
attr->detached = detachstate;
return 0;
}
-
-int
-pthread_attr_destroy(pthread_attr_t *attr)
-{
- if (is_attr(attr) != 0)
- {
- return EINVAL;
- }
-
- /* Set the attribute object to a specific invalid value. */
- attr->valid = _PTHREAD_ATTR_INVALID;
-
- return 0;
-}
diff --git a/implement.h b/implement.h
index ea68d2f..14fbdbb 100644
--- a/implement.h
+++ b/implement.h
@@ -51,13 +51,6 @@ struct _pthread_threads_thread {
pthread_t thread;
pthread_attr_t attr;
_pthread_call_t call;
- enum {
- _PTHREAD_CLEANUP_STACK,
- _PTHREAD_DESTRUCTOR_STACK,
- _PTHREAD_FORKPREPARE_STACK,
- _PTHREAD_FORKPARENT_STACK,
- _PTHREAD_FORKCHILD_STACK
- };
_pthread_handler_node_t * cleanupstack;
_pthread_handler_node_t * destructorstack;
_pthread_handler_node_t * forkpreparestack;
@@ -69,6 +62,19 @@ struct _pthread_threads_thread {
extern "C" {
#endif /* __cplusplus */
+/* Generic handler push and pop routines. */
+
+void _pthread_handler_push(_pthread_handler_node_t ** stacktop,
+ int poporder,
+ void (*routine)(void *),
+ void *arg);
+
+void _pthread_handler_pop(_pthread_handler_node_t ** stacktop,
+ int execute);
+
+void _pthread_handler_pop_all(_pthread_handler_node_t ** stacktop,
+ int execute);
+
/* Primitives to manage threads table entries. */
int _pthread_new_thread_entry(pthread_t thread,
@@ -87,6 +93,18 @@ void _pthread_vacuum(void);
#endif /* __cplusplus */
-#endif /* _IMPLEMENT_H */
+/* Global data declared in global.c */
+
+extern pthread_mutex_t _pthread_count_mutex;
+extern DWORD _pthread_threads_count;
+
+extern _pthread_threads_thread_t _pthread_threads_table[];
+
+extern unsigned short _pthread_once_flag;
+
+extern pthread_mutex_t _pthread_once_lock;
+
+
+#endif /* _IMPLEMENT_H */
diff --git a/private.c b/private.c
index 4e5f9ed..e65e95e 100644
--- a/private.c
+++ b/private.c
@@ -92,12 +92,12 @@ _pthread_find_thread_entry(pthread_t thread)
/* Wrap to top of table. */
this = _pthread_threads_table;
}
+ }
- if (this->thread == NULL || this == start)
- {
- /* Failed to find the thread. */
- return -1;
- }
+ if (this->thread == NULL || this == start)
+ {
+ /* Failed to find the thread. */
+ return -1;
}
return this;
diff --git a/pthread.h b/pthread.h
index 7f0ba89..dc3c608 100644
--- a/pthread.h
+++ b/pthread.h
@@ -58,19 +58,22 @@ typedef DWORD pthread_key_t;
/* Related constants */
typedef struct {
long valid;
+
#ifdef _POSIX_THREAD_ATTR_STACKSIZE
size_t stacksize; /* PTHREAD_STACK_MIN */
#endif
+
int cancelability; /* PTHREAD_CANCEL_DISABLE
PTHREAD_CANCEL_ENABLE */
+ int detached; /* PTHREAD_CREATE_DETACHED
+ PTHREAD_CREATE_JOINABLE */
+
int canceltype; /* PTHREAD_CANCEL_ASYNCHRONOUS
PTHREAD_CANCEL_DEFERRED */
- int detached; /* PTHREAD_CREATE_JOINABLE
- PTHREAD_CREATE_DETACHED */
-
int priority;
+
} pthread_attr_t;
/* I don't know why this structure isn't in some kind of namespace.
@@ -122,6 +125,8 @@ int pthread_equal(pthread_t t1, pthread_t t2);
int pthread_join(pthread_t thread, void ** valueptr);
+int pthread_detach(pthread_t thread);
+
int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));
/* Functions for manipulating thread attribute objects. */
@@ -238,22 +243,6 @@ void *pthread_getspecific(pthread_key_t key);
int pthread_key_delete(pthread_key_t key);
-
-/* Internal primitives that must be here. */
-
-/* Generic handler push and pop routines. */
-
-void _pthread_handler_push(_pthread_handler_node_t ** stacktop,
- int poporder,
- void (*routine)(void *),
- void *arg);
-
-void _pthread_handler_pop(_pthread_handler_node_t ** stacktop,
- int execute);
-
-void _pthread_handler_pop_all(_pthread_handler_node_t ** stacktop,
- int execute);
-
#ifdef __cplusplus
}
#endif /* __cplusplus */
@@ -266,13 +255,21 @@ void _pthread_handler_pop_all(_pthread_handler_node_t ** stacktop,
POSIX requires that applications observe scoping requirements, but
doesn't say if the implemention must enforce them. The macros below
- partially enforce scope but can lead to compile or runtime errors.
- */
+ partially enforce scope but can lead to compile or runtime errors. */
+
enum {
_PTHREAD_HANDLER_POP_LIFO,
_PTHREAD_HANDLER_POP_FIFO
};
+enum {
+ _PTHREAD_CLEANUP_STACK,
+ _PTHREAD_DESTRUCTOR_STACK,
+ _PTHREAD_FORKPREPARE_STACK,
+ _PTHREAD_FORKPARENT_STACK,
+ _PTHREAD_FORKCHILD_STACK
+};
+
#ifdef pthread_cleanup_push
#undef pthread_cleanup_push
#endif
@@ -290,19 +287,4 @@ enum {
_pthread_handler_pop(_PTHREAD_CLEANUP_STACK, execute);\
}
-
-/* Global data needed by the application but which must not be static
- in the DLL. */
-
-extern pthread_mutex_t _pthread_count_mutex;
-
-extern DWORD _pthread_threads_count;
-
-extern _pthread_threads_thread_t _pthread_threads_table[];
-
-extern unsigned short _pthread_once_flag;
-
-extern pthread_mutex_t _pthread_once_lock;
-
-
#endif /* _PTHREADS_H */
diff --git a/sync.c b/sync.c
index 20009ac..c3bd438 100644
--- a/sync.c
+++ b/sync.c
@@ -12,8 +12,7 @@ int
pthread_join(pthread_t thread, void ** valueptr)
{
LPDWORD exitcode;
- _pthread_threads_thread_t * target;
-
+ int detachstate;
pthread_t us = pthread_self();
/* First check if we are trying to join to ourselves. */
@@ -22,16 +21,20 @@ pthread_join(pthread_t thread, void ** valueptr)
return EDEADLK;
}
- /* If the thread is detached, then join will return immediately. */
+ /* Find the thread. */
+ this = _pthread_find_thread_entry(thread);
- target = _pthread_find_thread_entry(thread);
- if (target < 0)
+ if (this == -1)
{
- return EINVAL;
+ return ESRCH;
}
- else if (target->detached == PTHREAD_CREATE_DETACHED)
+
+ /* If the thread is detached, then join will return immediately. */
+
+ if (pthread_attr_getdetachedstate(&(this->attr), &detachstate) != 0
+ || detachstate == PTHREAD_CREATE_DETACHED)
{
- return ESRCH;
+ return EINVAL;
}
/* Wait on the kernel thread object. */
@@ -60,3 +63,26 @@ pthread_join(pthread_t thread, void ** valueptr)
return &exitcode;
}
+int
+pthread_detach(pthread_t thread)
+{
+ _pthread_threads_thread_t * this;
+ int detachstate;
+
+ this = _pthread_find_thread_entry(thread);
+
+ if (this = -1)
+ {
+ return ESRCH;
+ }
+
+ /* Check that we can detach this thread. */
+ if (pthread_attr_getdetachedstate(&(this->attr), &detachstate) != 0
+ || detachstate == PTHREAD_CREATE_DETACHED)
+ {
+ return EINVAL;
+ }
+
+ /* FIXME: As far as I can determine we just no-op. */
+ return 0;
+}