@@ -736,33 +736,21 @@ static void *thread_main(void *param)
736736
737737 return result ;
738738}
739- #endif
740739
741- /*
742- * pj_thread_create(...)
743- */
744- PJ_DEF (pj_status_t ) pj_thread_create ( pj_pool_t * pool ,
745- const char * thread_name ,
746- pj_thread_proc * proc ,
747- void * arg ,
748- pj_size_t stack_size ,
749- unsigned flags ,
750- pj_thread_t * * ptr_thread )
740+ static pj_status_t create_thread (const char * thread_name ,
741+ pj_thread_proc * proc ,
742+ void * arg ,
743+ pj_size_t stack_size ,
744+ void * stack_addr ,
745+ pj_thread_t * rec )
751746{
752- #if PJ_HAS_THREADS
753- pj_thread_t * rec ;
754747 pthread_attr_t thread_attr ;
755- void * stack_addr ;
756748 int rc ;
757749
758750 PJ_UNUSED_ARG (stack_addr );
759751
760752 PJ_CHECK_STACK ();
761- PJ_ASSERT_RETURN (pool && proc && ptr_thread , PJ_EINVAL );
762-
763- /* Create thread record and assign name for the thread */
764- rec = (struct pj_thread_t * ) pj_pool_zalloc (pool , sizeof (pj_thread_t ));
765- PJ_ASSERT_RETURN (rec , PJ_ENOMEM );
753+ PJ_ASSERT_RETURN (proc && rec , PJ_EINVAL );
766754
767755 /* Set name. */
768756 if (!thread_name )
@@ -783,19 +771,6 @@ PJ_DEF(pj_status_t) pj_thread_create( pj_pool_t *pool,
783771 rec -> stk_max_usage = 0 ;
784772#endif
785773
786- /* Emulate suspended thread with mutex. */
787- if (flags & PJ_THREAD_SUSPENDED ) {
788- rc = pj_mutex_create_simple (pool , NULL , & rec -> suspended_mutex );
789- if (rc != PJ_SUCCESS ) {
790- return rc ;
791- }
792-
793- pj_mutex_lock (rec -> suspended_mutex );
794- } else {
795- pj_assert (rec -> suspended_mutex == NULL );
796- }
797-
798-
799774 /* Init thread attributes */
800775 pthread_attr_init (& thread_attr );
801776
@@ -811,8 +786,7 @@ PJ_DEF(pj_status_t) pj_thread_create( pj_pool_t *pool,
811786
812787#if defined(PJ_THREAD_ALLOCATE_STACK ) && PJ_THREAD_ALLOCATE_STACK != 0
813788 /* Allocate memory for the stack */
814- stack_addr = pj_pool_alloc (pool , stack_size );
815- PJ_ASSERT_RETURN (stack_addr , PJ_ENOMEM );
789+ PJ_ASSERT_RETURN (stack_addr , PJ_EINVAL );
816790
817791 rc = pthread_attr_setstackaddr (& thread_attr , stack_addr );
818792 if (rc != 0 ) {
@@ -834,10 +808,85 @@ PJ_DEF(pj_status_t) pj_thread_create( pj_pool_t *pool,
834808 /* Destroy thread attributes */
835809 pthread_attr_destroy (& thread_attr );
836810
837- * ptr_thread = rec ;
838-
839811 PJ_LOG (6 , (rec -> obj_name , "Thread created" ));
840812 return PJ_SUCCESS ;
813+
814+ }
815+
816+ #endif
817+
818+ /*
819+ * pj_thread_create(...)
820+ */
821+ PJ_DEF (pj_status_t ) pj_thread_create ( pj_pool_t * pool ,
822+ const char * thread_name ,
823+ pj_thread_proc * proc ,
824+ void * arg ,
825+ pj_size_t stack_size ,
826+ unsigned flags ,
827+ pj_thread_t * * ptr_thread )
828+ {
829+ #if PJ_HAS_THREADS
830+ pj_status_t status ;
831+ pj_thread_t * rec ;
832+ void * stack_addr = NULL ;
833+ int rc ;
834+
835+ PJ_CHECK_STACK ();
836+ PJ_ASSERT_RETURN (pool && proc && ptr_thread , PJ_EINVAL );
837+
838+ /* Create thread record and assign name for the thread */
839+ rec = (struct pj_thread_t * ) pj_pool_zalloc (pool , sizeof (pj_thread_t ));
840+ PJ_ASSERT_RETURN (rec , PJ_ENOMEM );
841+
842+ #if defined(PJ_THREAD_ALLOCATE_STACK ) && PJ_THREAD_ALLOCATE_STACK != 0
843+ /* Allocate memory for the stack */
844+ stack_addr = pj_pool_alloc (pool , stack_size );
845+ PJ_ASSERT_RETURN (stack_addr , PJ_ENOMEM );
846+ #endif /* PJ_THREAD_ALLOCATE_STACK */
847+
848+ /* Emulate suspended thread with mutex. */
849+ if (flags & PJ_THREAD_SUSPENDED ) {
850+ rc = pj_mutex_create_simple (pool , NULL , & rec -> suspended_mutex );
851+ if (rc != PJ_SUCCESS ) {
852+ return rc ;
853+ }
854+
855+ pj_mutex_lock (rec -> suspended_mutex );
856+ } else {
857+ pj_assert (rec -> suspended_mutex == NULL );
858+ }
859+
860+ status = create_thread (thread_name , proc , arg , stack_size , stack_addr , rec );
861+ if (status == PJ_SUCCESS ) {
862+ /* Success! */
863+ * ptr_thread = rec ;
864+ }
865+ return status ;
866+
867+ #else
868+ pj_assert (!"Threading is disabled!" );
869+ return PJ_EINVALIDOP ;
870+ #endif
871+ }
872+
873+ PJ_DEF (pj_status_t ) pj_thread_create2 ( const char * thread_name ,
874+ pj_thread_proc * proc ,
875+ void * arg ,
876+ pj_size_t stack_size ,
877+ void * stack_addr ,
878+ pj_thread_t * thread )
879+ {
880+ #if PJ_HAS_THREADS
881+
882+ PJ_CHECK_STACK ();
883+ PJ_ASSERT_RETURN (proc && thread , PJ_EINVAL );
884+
885+ if (thread == pj_thread_this ())
886+ return PJ_ECANCELLED ;
887+
888+ return create_thread (thread_name , proc , arg , stack_size , stack_addr , thread );
889+
841890#else
842891 pj_assert (!"Threading is disabled!" );
843892 return PJ_EINVALIDOP ;
@@ -937,12 +986,49 @@ PJ_DEF(pj_status_t) pj_thread_join(pj_thread_t *p)
937986#endif
938987}
939988
989+ /*
990+ * pj_thread_unregister()
991+ */
992+ PJ_DEF (pj_status_t ) pj_thread_unregister ()
993+ {
994+ #if PJ_HAS_THREADS
995+ pj_status_t status ;
996+ //int result;
997+ pj_thread_t * rec ;
998+ PJ_CHECK_STACK ();
999+
1000+ rec = pj_thread_this ();
1001+ PJ_ASSERT_RETURN (rec , PJ_EBUG );
1002+
1003+ if ((status = pj_thread_destroy (rec )) != PJ_SUCCESS )
1004+ return status ;
1005+ //else if ((result = pthread_detach(rec->thread)) != 0)
1006+ // return PJ_RETURN_OS_ERROR(result);
1007+ else
1008+ return pj_thread_local_set (thread_tls_id , NULL );
1009+ #else
1010+ pj_assert (!"No multithreading support!" );
1011+ return PJ_EINVALIDOP ;
1012+ #endif
1013+ }
1014+
1015+ /*
1016+ * pj_thread_attach()
1017+ */
1018+ PJ_DEF (pj_status_t ) pj_thread_attach (const char * cstr_thread_name ,
1019+ pj_thread_desc desc ,
1020+ pj_thread_t * * thread_ptr )
1021+ {
1022+ return pj_thread_register (cstr_thread_name , desc , thread_ptr );
1023+ }
1024+
9401025/*
9411026 * pj_thread_destroy()
9421027 */
9431028PJ_DEF (pj_status_t ) pj_thread_destroy (pj_thread_t * p )
9441029{
9451030 PJ_CHECK_STACK ();
1031+ PJ_ASSERT_RETURN (p , PJ_EINVAL );
9461032
9471033 /* Destroy mutex used to suspend thread */
9481034 if (p -> suspended_mutex ) {
@@ -1005,7 +1091,13 @@ PJ_DEF(void) pj_thread_check_stack(const char *file, int line)
10051091{
10061092 char stk_ptr ;
10071093 pj_uint32_t usage ;
1008- pj_thread_t * thread = pj_thread_this ();
1094+ pj_thread_t * thread ;
1095+
1096+ /* may be called after pj_thread_unregister() */
1097+ if (!pj_thread_is_registered ())
1098+ return ;
1099+
1100+ thread = pj_thread_this ();
10091101
10101102 /* Calculate current usage. */
10111103 usage = (& stk_ptr > thread -> stk_start ) ? & stk_ptr - thread -> stk_start :
0 commit comments