replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / service / notification / src / provider / NSProviderScheduler.c
index fb49337..2dddff0 100755 (executable)
-//******************************************************************\r
-//\r
-// Copyright 2016 Samsung Electronics All Rights Reserved.\r
-//\r
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
-//\r
-// Licensed under the Apache License, Version 2.0 (the "License");\r
-// you may not use this file except in compliance with the License.\r
-// You may obtain a copy of the License at\r
-//\r
-//      http://www.apache.org/licenses/LICENSE-2.0\r
-//\r
-// Unless required by applicable law or agreed to in writing, software\r
-// distributed under the License is distributed on an "AS IS" BASIS,\r
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-// See the License for the specific language governing permissions and\r
-// limitations under the License.\r
-//\r
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
-\r
-#include "NSProviderScheduler.h"\r
-\r
-pthread_t NSThread[THREAD_COUNT];\r
-pthread_mutex_t NSMutex[THREAD_COUNT];\r
-sem_t NSSemaphore[THREAD_COUNT];\r
-bool NSIsRunning[THREAD_COUNT] = { false, };\r
-\r
-NSTask* NSHeadMsg[THREAD_COUNT];\r
-NSTask* NSTailMsg[THREAD_COUNT];\r
-\r
-void * NSCallbackResponseSchedule(void *ptr);\r
-void * NSDiscoverySchedule(void *ptr);\r
-void * NSSubScriptionSchedule(void *ptr);\r
-void * NSNotificationSchedule(void *ptr);\r
-void * NSTopicSchedule(void * ptr);\r
-\r
-bool NSInitScheduler()\r
-{\r
-    NS_LOG(DEBUG, "NSInitScheduler - IN");\r
-\r
-    int i = 0;\r
-\r
-    for (i = 0; i < THREAD_COUNT; i++)\r
-    {\r
-        pthread_mutex_init(&NSMutex[i], NULL);\r
-        NSIsRunning[i] = true;\r
-        sem_init(&(NSSemaphore[i]), 0, 0);\r
-    }\r
-\r
-    NS_LOG(DEBUG, "NSInitScheduler - OUT");\r
-\r
-    return true;\r
-}\r
-\r
-bool NSStartScheduler()\r
-{\r
-    int i = 0;\r
-\r
-    for (i = 0; i < THREAD_COUNT; i++)\r
-    {\r
-        pthread_mutex_lock(&NSMutex[i]);\r
-\r
-        switch (i)\r
-        {\r
-            case CALLBACK_RESPONSE_SCHEDULER:\r
-            {\r
-                NS_LOG(DEBUG, "CASE RESPONSE_SCHEDULER :");\r
-                pthread_create(&NSThread[i], NULL, NSCallbackResponseSchedule, NULL);\r
-            }\r
-                break;\r
-\r
-            case DISCOVERY_SCHEDULER:\r
-            {\r
-                NS_LOG(DEBUG, "CASE DISCOVERY_SCHEDULER :");\r
-                pthread_create(&NSThread[i], NULL, NSDiscoverySchedule, NULL);\r
-            }\r
-                break;\r
-\r
-            case SUBSCRIPTION_SCHEDULER:\r
-            {\r
-                NS_LOG(DEBUG, "CASE SUBSCRIPTION_SCHEDULER :");\r
-                pthread_create(&NSThread[i], NULL, NSSubScriptionSchedule, NULL);\r
-            }\r
-                break;\r
-\r
-            case NOTIFICATION_SCHEDULER:\r
-            {\r
-                NS_LOG(DEBUG, "CASE NOTIFICATION_SCHEDULER :");\r
-                pthread_create(&NSThread[i], NULL, NSNotificationSchedule, NULL);\r
-            }\r
-                break;\r
-\r
-            case TOPIC_SCHEDULER:\r
-            {\r
-                NS_LOG(DEBUG, "CASE TOPIC_SCHEDULER :");\r
-                pthread_create(&NSThread[i], NULL, NSTopicSchedule, NULL);\r
-            }\r
-                break;\r
-            default:\r
-                break;\r
-\r
-        }\r
-\r
-        NSHeadMsg[i] = NSTailMsg[i] = NULL;\r
-\r
-        pthread_mutex_unlock(&NSMutex[i]);\r
-\r
-    }\r
-\r
-    return true;\r
-}\r
-\r
-bool NSStopScheduler()\r
-{\r
-    NS_LOG(DEBUG, "NSStopScheduler - IN");\r
-    int i = 0;\r
-\r
-    for (i = THREAD_COUNT - 1; i >= 0; --i)\r
-    {\r
-        int status = -1;\r
-\r
-        NSIsRunning[i] = false;\r
-\r
-        sem_post(&(NSSemaphore[i]));\r
-        pthread_join(NSThread[i], (void **) &status);\r
-\r
-        NSThread[i] = 0;\r
-\r
-        pthread_mutex_lock(&NSMutex[i]);\r
-\r
-        while (NSHeadMsg[i] != NULL)\r
-        {\r
-            NSTask* temp = NSHeadMsg[i];\r
-            NSHeadMsg[i] = NSHeadMsg[i]->nextTask;\r
-            NSFreeData(i, temp);\r
-            OICFree(temp);\r
-        }\r
-\r
-        NSTailMsg[i] = NSHeadMsg[i] = NULL;\r
-\r
-        pthread_mutex_unlock(&NSMutex[i]);\r
-        pthread_mutex_destroy(&NSMutex[i]);\r
-    }\r
-\r
-    NS_LOG(DEBUG, "NSStopScheduler - OUT");\r
-\r
-    return true;\r
-}\r
-\r
-void NSPushQueue(NSSchedulerType schedulerType, NSTaskType taskType, void* data)\r
-{\r
-\r
-    if(!NSIsRunning[schedulerType])\r
-    {\r
-        return;\r
-    }\r
-\r
-    pthread_mutex_lock(&NSMutex[schedulerType]);\r
-\r
-    NS_LOG(DEBUG, "NSPushQueue - IN");\r
-    NS_LOG_V(DEBUG, "NSSchedulerType = %d", schedulerType);\r
-    NS_LOG_V(DEBUG, "NSTaskType = %d", taskType);\r
-\r
-    if (NSHeadMsg[schedulerType] == NULL)\r
-    {\r
-        NSHeadMsg[schedulerType] = (NSTask*) OICMalloc(sizeof(NSTask));\r
-        if(NSHeadMsg[schedulerType])\r
-        {\r
-            NSHeadMsg[schedulerType]->taskType = taskType;\r
-            NSHeadMsg[schedulerType]->taskData = data;\r
-            NSHeadMsg[schedulerType]->nextTask = NULL;\r
-            NSTailMsg[schedulerType] = NSHeadMsg[schedulerType];\r
-        }\r
-    }\r
-    else\r
-    {\r
-        NSTask* newNode = (NSTask*) OICMalloc(sizeof(NSTask));\r
-        if(newNode)\r
-        {\r
-            newNode->taskType = taskType;\r
-            newNode->taskData = data;\r
-            newNode->nextTask = NULL;\r
-\r
-            NSTailMsg[schedulerType]->nextTask = newNode;\r
-            NSTailMsg[schedulerType] = newNode;\r
-        }\r
-    }\r
-\r
-    sem_post(&(NSSemaphore[schedulerType]));\r
-    NS_LOG(DEBUG, "NSPushQueue - OUT");\r
-    pthread_mutex_unlock(&NSMutex[schedulerType]);\r
-}\r
-\r
-void NSFreeData(NSSchedulerType type, NSTask * task)\r
-{\r
-    NS_LOG(DEBUG, "NSFreeData - IN");\r
-\r
-    if (type == CALLBACK_RESPONSE_SCHEDULER)\r
-    {\r
-        switch (task->taskType)\r
-        {\r
-            case TASK_CB_SUBSCRIPTION:\r
-                NS_LOG(DEBUG, "CASE TASK_CB_SUBSCRIPTION : Free");\r
-                NSFreeOCEntityHandlerRequest((OCEntityHandlerRequest*) task->taskData);\r
-                break;\r
-            case TASK_CB_SYNC:\r
-                NS_LOG(DEBUG, "CASE TASK_CB_SYNC : Free");\r
-                NSFreeSync((NSSyncInfo*) task->taskData);\r
-                break;\r
-            default:\r
-                NS_LOG(DEBUG, "No Task Type");\r
-                break;\r
-        }\r
-    }\r
-    else if (type == DISCOVERY_SCHEDULER)\r
-    {\r
-        switch (task->taskType)\r
-        {\r
-            case TASK_START_PRESENCE:\r
-            case TASK_STOP_PRESENCE:\r
-            case TASK_REGISTER_RESOURCE:\r
-                NS_LOG(DEBUG, "Not required Free");\r
-                break;\r
-            default:\r
-                NS_LOG(DEBUG, "No Task Type");\r
-                break;\r
-        }\r
-    }\r
-    else if (type == SUBSCRIPTION_SCHEDULER)\r
-    {\r
-        switch (task->taskType)\r
-        {\r
-            case TASK_SEND_POLICY:\r
-            case TASK_RECV_SUBSCRIPTION:\r
-            case TASK_RECV_UNSUBSCRIPTION:\r
-            case TASK_SYNC_SUBSCRIPTION:\r
-                NS_LOG(DEBUG, "NSFreeOCEntityHandlerRequest : Free ");\r
-                NSFreeOCEntityHandlerRequest((OCEntityHandlerRequest*) task->taskData);\r
-                break;\r
-            case TASK_SEND_ALLOW:\r
-            case TASK_SEND_DENY:\r
-                NS_LOG(DEBUG, "NSFreeConsumer : Free ");\r
-                NSFreeConsumer((NSConsumer *) task->taskData);\r
-                break;\r
-            default:\r
-                NS_LOG(DEBUG, "No Task Type");\r
-                break;\r
-        }\r
-    }\r
-    else if (type == NOTIFICATION_SCHEDULER)\r
-    {\r
-        switch (task->taskType)\r
-        {\r
-            case TASK_SEND_NOTIFICATION:\r
-            {\r
-                NS_LOG(DEBUG, "NSFreeMessage : Free ");\r
-                NSFreeMessage((NSMessage *)task->taskData);\r
-                break;\r
-            }\r
-            case TASK_SEND_READ:\r
-            case TASK_RECV_READ:\r
-                NS_LOG(DEBUG, "NSFreeSync : Free ");\r
-                NSFreeSync((NSSyncInfo*) task->taskData);\r
-                break;\r
-\r
-            default:\r
-                NS_LOG(DEBUG, "No Task Type");\r
-                break;\r
-        }\r
-    }\r
-    else if (type == TOPIC_SCHEDULER)\r
-    {\r
-        switch (task->taskType)\r
-        {\r
-            case TASK_SUBSCRIBE_TOPIC:\r
-            case TASK_UNSUBSCRIBE_TOPIC:\r
-            {\r
-                NSCacheTopicSubData * data = task->taskData;\r
-                OICFree(data->topicName);\r
-                OICFree(data);\r
-            }\r
-                break;\r
-            case TASK_REGISTER_TOPIC:\r
-            case TASK_UNREGISTER_TOPIC:\r
-            {\r
-                OICFree(task->taskData);\r
-            }\r
-                break;\r
-            case TASK_SEND_TOPICS:\r
-            case TASK_POST_TOPIC:\r
-            {\r
-                NS_LOG(DEBUG, "TASK_POST_TOPIC : ");\r
-                NSFreeOCEntityHandlerRequest((OCEntityHandlerRequest*) task->taskData);\r
-            }\r
-                break;\r
-            default:\r
-                break;\r
-        }\r
-    }\r
-    NS_LOG(DEBUG, "NSFreeData - OUT");\r
-}\r
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "NSProviderScheduler.h"
+
+#ifdef __TIZENRT__
+#include <tinyara/config.h>
+#endif
+
+pthread_t NSThread[THREAD_COUNT];
+pthread_mutex_t NSMutex[THREAD_COUNT];
+sem_t NSSemaphore[THREAD_COUNT];
+bool NSIsRunning[THREAD_COUNT] = { false, };
+
+NSTask* NSHeadMsg[THREAD_COUNT];
+NSTask* NSTailMsg[THREAD_COUNT];
+
+void * NSCallbackResponseSchedule(void *ptr);
+void * NSDiscoverySchedule(void *ptr);
+void * NSSubScriptionSchedule(void *ptr);
+void * NSNotificationSchedule(void *ptr);
+void * NSTopicSchedule(void * ptr);
+
+bool NSInitScheduler()
+{
+    NS_LOG(DEBUG, "NSInitScheduler - IN");
+
+    int i = 0;
+
+    for (i = 0; i < THREAD_COUNT; i++)
+    {
+        pthread_mutex_init(&NSMutex[i], NULL);
+        NSIsRunning[i] = true;
+        sem_init(&(NSSemaphore[i]), 0, 0);
+    }
+
+    NS_LOG(DEBUG, "NSInitScheduler - OUT");
+
+    return true;
+}
+
+#ifdef __TIZENRT__
+static int ns_pthread_create(pthread_t *thread, pthread_startroutine_t start_routine,
+                             pthread_addr_t arg, const char *task_name, int stack_size)
+{
+/* All callers have null attr, so ignore it for simple implementation*/
+    pthread_attr_t task_attr;
+
+    pthread_attr_init(&task_attr);
+
+    (void)pthread_attr_setschedparam(&task_attr, PTHREAD_DEFAULT_PRIORITY);
+    (void)pthread_attr_setstacksize(&task_attr, stack_size);
+
+    int ret = pthread_create(thread, &task_attr, start_routine, NULL);
+    if (ret)
+    {
+        return ret;
+    }
+
+    pthread_setname_np(*thread, task_name);
+
+    return 0;
+}
+#endif
+
+bool NSStartScheduler()
+{
+    int i = 0;
+
+    for (i = 0; i < THREAD_COUNT; i++)
+    {
+        pthread_mutex_lock(&NSMutex[i]);
+
+        switch (i)
+        {
+            case CALLBACK_RESPONSE_SCHEDULER:
+            {
+                NS_LOG(DEBUG, "CASE RESPONSE_SCHEDULER :");
+#ifdef __TIZENRT__
+                ns_pthread_create(&NSThread[i], NSCallbackResponseSchedule, NULL,
+                                  "IoT_NS_CallbackResponseSchedule",
+                                  CONFIG_IOTIVITY_NS_CALLBACKRESPONSESCHED_PTHREAD_STACKSIZE);
+#else
+                pthread_create(&NSThread[i], NULL, NSCallbackResponseSchedule, NULL);
+#endif
+            }
+                break;
+
+            case DISCOVERY_SCHEDULER:
+            {
+                NS_LOG(DEBUG, "CASE DISCOVERY_SCHEDULER :");
+#ifdef __TIZENRT__
+                ns_pthread_create(&NSThread[i], NSDiscoverySchedule, NULL,
+                                  "IoT_NS_DiscoverySchedule",
+                                  CONFIG_IOTIVITY_NS_DISCOVERSCHED_PTHREAD_STACKSIZE);
+#else
+                pthread_create(&NSThread[i], NULL, NSDiscoverySchedule, NULL);
+#endif
+            }
+                break;
+
+            case SUBSCRIPTION_SCHEDULER:
+            {
+                NS_LOG(DEBUG, "CASE SUBSCRIPTION_SCHEDULER :");
+#ifdef __TIZENRT__
+                ns_pthread_create(&NSThread[i], NSSubScriptionSchedule, NULL,
+                                  "IOT_NS_SubScriptionSchedule",
+                                  CONFIG_IOTIVITY_NS_SUBSCRIPTIONSCHED_PTHREAD_STACKSIZE);
+#else
+                pthread_create(&NSThread[i], NULL, NSSubScriptionSchedule, NULL);
+#endif
+            }
+                break;
+
+            case NOTIFICATION_SCHEDULER:
+            {
+                NS_LOG(DEBUG, "CASE NOTIFICATION_SCHEDULER :");
+#ifdef __TIZENRT__
+                ns_pthread_create(&NSThread[i], NSNotificationSchedule, NULL,
+                                  "IoT_NS_NotificationSchedule",
+                                  CONFIG_IOTIVITY_NS_NOTIFICATIONSCHED_PTHREAD_STACKSIZE);
+#else
+                pthread_create(&NSThread[i], NULL, NSNotificationSchedule, NULL);
+#endif
+            }
+                break;
+
+            case TOPIC_SCHEDULER:
+            {
+                NS_LOG(DEBUG, "CASE TOPIC_SCHEDULER :");
+#ifdef __TIZENRT__
+                ns_pthread_create(&NSThread[i], NSTopicSchedule, NULL, "IoT_NS_TopicSchedule",
+                                  CONFIG_IOTIVITY_NS_TOPICSCHED_PTHREAD_STACKSIZE);
+#else
+                pthread_create(&NSThread[i], NULL, NSTopicSchedule, NULL);
+#endif
+            }
+                break;
+            default:
+                break;
+
+        }
+
+        NSHeadMsg[i] = NSTailMsg[i] = NULL;
+
+        pthread_mutex_unlock(&NSMutex[i]);
+
+    }
+
+    return true;
+}
+
+bool NSStopScheduler()
+{
+    NS_LOG(DEBUG, "NSStopScheduler - IN");
+    int i = 0;
+
+    for (i = THREAD_COUNT - 1; i >= 0; --i)
+    {
+        int status = -1;
+
+        NSIsRunning[i] = false;
+
+        sem_post(&(NSSemaphore[i]));
+        pthread_join(NSThread[i], (void **) &status);
+
+        NSThread[i] = 0;
+
+        pthread_mutex_lock(&NSMutex[i]);
+
+        while (NSHeadMsg[i] != NULL)
+        {
+            NSTask* temp = NSHeadMsg[i];
+            NSHeadMsg[i] = NSHeadMsg[i]->nextTask;
+            NSFreeData(i, temp);
+            NSOICFree(temp);
+        }
+
+        NSTailMsg[i] = NSHeadMsg[i] = NULL;
+
+        pthread_mutex_unlock(&NSMutex[i]);
+        pthread_mutex_destroy(&NSMutex[i]);
+    }
+
+    NS_LOG(DEBUG, "NSStopScheduler - OUT");
+
+    return true;
+}
+
+void NSPushQueue(NSSchedulerType schedulerType, NSTaskType taskType, void* data)
+{
+
+    if (!NSIsRunning[schedulerType])
+    {
+        return;
+    }
+
+    pthread_mutex_lock(&NSMutex[schedulerType]);
+
+    NS_LOG(DEBUG, "NSPushQueue - IN");
+    NS_LOG_V(DEBUG, "NSSchedulerType = %d", schedulerType);
+    NS_LOG_V(DEBUG, "NSTaskType = %d", taskType);
+
+    if (NSHeadMsg[schedulerType] == NULL)
+    {
+        NSHeadMsg[schedulerType] = (NSTask*) OICMalloc(sizeof(NSTask));
+
+        if (NSHeadMsg[schedulerType])
+        {
+            NSHeadMsg[schedulerType]->taskType = taskType;
+            NSHeadMsg[schedulerType]->taskData = data;
+            NSHeadMsg[schedulerType]->nextTask = NULL;
+            NSTailMsg[schedulerType] = NSHeadMsg[schedulerType];
+        }
+    }
+    else
+    {
+        NSTask* newNode = (NSTask*) OICMalloc(sizeof(NSTask));
+        if (newNode)
+        {
+            newNode->taskType = taskType;
+            newNode->taskData = data;
+            newNode->nextTask = NULL;
+
+            NSTailMsg[schedulerType]->nextTask = newNode;
+            NSTailMsg[schedulerType] = newNode;
+        }
+    }
+
+    sem_post(&(NSSemaphore[schedulerType]));
+    NS_LOG(DEBUG, "NSPushQueue - OUT");
+    pthread_mutex_unlock(&NSMutex[schedulerType]);
+}
+
+void NSFreeData(NSSchedulerType type, NSTask * task)
+{
+    NS_LOG(DEBUG, "NSFreeData - IN");
+
+    if (type == CALLBACK_RESPONSE_SCHEDULER)
+    {
+        switch (task->taskType)
+        {
+            case TASK_CB_SUBSCRIPTION:
+                NS_LOG(DEBUG, "CASE TASK_CB_SUBSCRIPTION : Free");
+                NSFreeOCEntityHandlerRequest((OCEntityHandlerRequest*) task->taskData);
+                break;
+            case TASK_CB_SYNC:
+                NS_LOG(DEBUG, "CASE TASK_CB_SYNC : Free");
+                NSFreeSync((NSSyncInfo*) task->taskData);
+                break;
+            default:
+                NS_LOG(DEBUG, "No Task Type");
+                break;
+        }
+    }
+    else if (type == DISCOVERY_SCHEDULER)
+    {
+        switch (task->taskType)
+        {
+            case TASK_START_PRESENCE:
+            case TASK_STOP_PRESENCE:
+            case TASK_REGISTER_RESOURCE:
+                NS_LOG(DEBUG, "Not required Free");
+                break;
+            default:
+                NS_LOG(DEBUG, "No Task Type");
+                break;
+        }
+    }
+    else if (type == SUBSCRIPTION_SCHEDULER)
+    {
+        switch (task->taskType)
+        {
+            case TASK_SEND_POLICY:
+            case TASK_RECV_SUBSCRIPTION:
+            case TASK_RECV_UNSUBSCRIPTION:
+            case TASK_SYNC_SUBSCRIPTION:
+                NS_LOG(DEBUG, "NSFreeOCEntityHandlerRequest : Free ");
+                NSFreeOCEntityHandlerRequest((OCEntityHandlerRequest*) task->taskData);
+                break;
+            case TASK_SEND_ALLOW:
+            case TASK_SEND_DENY:
+                NS_LOG(DEBUG, "NSFreeConsumer : Free ");
+                NSFreeConsumer((NSConsumer *) task->taskData);
+                break;
+            default:
+                NS_LOG(DEBUG, "No Task Type");
+                break;
+        }
+    }
+    else if (type == NOTIFICATION_SCHEDULER)
+    {
+        switch (task->taskType)
+        {
+            case TASK_SEND_NOTIFICATION:
+            {
+                NS_LOG(DEBUG, "NSFreeMessage : Free ");
+                NSFreeMessage((NSMessage *)task->taskData);
+                break;
+            }
+            case TASK_SEND_READ:
+            case TASK_RECV_READ:
+                NS_LOG(DEBUG, "NSFreeSync : Free ");
+                NSFreeSync((NSSyncInfo*) task->taskData);
+                break;
+
+            default:
+                NS_LOG(DEBUG, "No Task Type");
+                break;
+        }
+    }
+    else if (type == TOPIC_SCHEDULER)
+    {
+        switch (task->taskType)
+        {
+            case TASK_SUBSCRIBE_TOPIC:
+            case TASK_UNSUBSCRIBE_TOPIC:
+            {
+                NSCacheTopicSubData * data = task->taskData;
+                NSOICFree(data->topicName);
+                NSOICFree(data);
+            }
+                break;
+            case TASK_REGISTER_TOPIC:
+            case TASK_UNREGISTER_TOPIC:
+            {
+                NSOICFree(task->taskData);
+            }
+                break;
+            case TASK_SEND_TOPICS:
+            case TASK_POST_TOPIC:
+            {
+                NS_LOG(DEBUG, "TASK_POST_TOPIC : ");
+                NSFreeOCEntityHandlerRequest((OCEntityHandlerRequest*) task->taskData);
+            }
+                break;
+            default:
+                break;
+        }
+    }
+    NS_LOG(DEBUG, "NSFreeData - OUT");
+}