[IOT-1558] Add notification consumer for windows.
[iotivity.git] / service / notification / src / consumer / NSThread.c
1 //******************************************************************
2 //
3 // Copyright 2016 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include "NSThread.h"
22
23 #include "NSConstants.h"
24 #include "NSConsumerCommon.h"
25
26 #include <memory.h>
27 #include "oic_malloc.h"
28
29 #ifndef SYSTEM_WINDOWS
30 #include <pthread.h>
31
32 typedef struct
33 {
34     pthread_mutex_t mutex;
35 } oc_mutex_ns_internal;
36 #endif
37
38 NSConsumerThread * NSThreadInit(NSThreadFunc func, void * data)
39 {
40     NS_VERIFY_NOT_NULL(func, NULL);
41
42     NSConsumerThread * handle = (NSConsumerThread *)OICMalloc(sizeof(NSConsumerThread));
43     NS_VERIFY_NOT_NULL(handle, NULL);
44
45     memset(handle, 0, sizeof(NSConsumerThread));
46
47 #ifndef SYSTEM_WINDOWS
48     oc_mutex_ns_internal * mutexInfo
49         = (oc_mutex_ns_internal *) OICMalloc(sizeof(oc_mutex_ns_internal));
50     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(mutexInfo, NULL, NSDestroyThreadHandle(handle));
51
52     pthread_mutexattr_t * mutex_attr
53         = (pthread_mutexattr_t *) OICMalloc(sizeof(pthread_mutexattr_t));
54     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(mutex_attr, NULL,
55               {
56                   NSOICFree(mutexInfo);
57                   NSDestroyThreadHandle(handle));
58               }
59     int pthreadResult = pthread_mutexattr_settype(mutex_attr, PTHREAD_MUTEX_RECURSIVE);
60     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(pthreadResult == 0 ? (void *)1 : NULL, NULL,
61             {
62                     NSOICFree(mutexInfo);
63                     NSOICFree(mutex_attr);
64                     NSDestroyThreadHandle(handle);
65             });
66
67     pthreadResult = pthread_mutex_init(& (mutexInfo->mutex), mutex_attr);
68     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(pthreadResult == 0 ? (void *)1 : NULL, NULL,
69             {
70                     NSOICFree(mutexInfo);
71                     pthread_mutexattr_destroy(mutex_attr);
72                     NSOICFree(mutex_attr);
73                     NSDestroyThreadHandle(handle);
74             });
75     pthread_mutexattr_destroy(mutex_attr);
76     NSOICFree(mutex_attr);
77     handle->mutex = (oc_mutex) mutexInfo;
78 #else
79     handle->mutex = oc_mutex_new();
80     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(handle->mutex, NULL, NSDestroyThreadHandle(handle));
81 #endif
82
83     handle->isStarted = true;
84
85     OCThreadResult_t ret = oc_thread_new(& handle->thread_id, func,
86                              (data == NULL) ? (void *) handle : (void *)data);
87     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(ret == OC_THREAD_SUCCESS ? (void*)1 : NULL, NULL,
88             NSDestroyThreadHandle(handle));
89
90     return handle;
91 }
92
93 void NSThreadLock(NSConsumerThread * handle)
94 {
95     NS_VERIFY_NOT_NULL_V(handle);
96
97     oc_mutex_lock(handle->mutex);
98 }
99
100 void NSThreadUnlock(NSConsumerThread * handle)
101 {
102     NS_VERIFY_NOT_NULL_V(handle);
103
104     oc_mutex_unlock(handle->mutex);
105 }
106
107 void NSThreadJoin(NSConsumerThread * handle)
108 {
109     NS_VERIFY_NOT_NULL_V(handle);
110
111     if (handle->isStarted)
112     {
113         oc_thread_wait(handle->thread_id);
114     }
115 }
116
117 void NSThreadStop(NSConsumerThread * handle)
118 {
119     NS_VERIFY_NOT_NULL_V(handle);
120
121     handle->isStarted = false;
122     NSThreadJoin(handle);
123
124     NSDestroyThreadHandle(handle);
125 }
126
127 void NSDestroyThreadHandle(NSConsumerThread * handle)
128 {
129     NS_VERIFY_NOT_NULL_V(handle);
130
131     oc_mutex_free(handle->mutex);
132 }