1 /*
2  * Copyright 1999-2006 University of Chicago
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * 
8  * http://www.apache.org/licenses/LICENSE-2.0
9  * 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "globus_i_wsrf_service_group.h"
18
19 /**
20  * Destroy the state associated with a service group
21  * @ingroup wssg
22  *
23  * Clean up the memory used by the service group associated with the resource
24  * named by @a service_group_epr. All entry resources created by the service
25  * group are destroyed. The service group may no longer be accessed.
26  *
27  * @param service_group_epr
28  *     An EPR naming the resource which contains the service group.
29  *
30  * @retval GLOBUS_SUCCESS
31  *     Service group state successfully destroyed.
32  * @retval GLOBUS_SERVICE_GROUP_ERROR_TYPE_NULL_PARAMETER 
33  *     The @a service_group_epr parameter was NULL.
34  * @retval GLOBUS_SERVICE_GROUP_ERROR_TYPE_UNKNOWN
35  *     There is no service group associated with the resource named by
36  *     @a service_group_epr.
37  */
38 globus_result_t
39 globus_service_group_destroy(
40     const wsa_EndpointReferenceType *   service_group_epr)
41 17 {
42 17     globus_wsrf_service_group_t         sg;
43 17     char *                              resource_id;
44 17     globus_result_t                     result;
45 17     GlobusFuncName(globus_service_group_destroy);
46
47 17     GlobusServiceGroupDebugEnter();
48
49 17     if (service_group_epr == NULL)
50     {
51 1         result = GLOBUS_SERVICE_GROUP_NULL_PARAMETER();
52
53 1         goto out;
54     }
55     /* This function removes the service group from the global table
56      * and then calls globus_i_service_group_destroy() to actually destroy it.
57      * That function is also used in module deactivation when the
58      * service group hash is being destroyed
59      */
60 16     result = globus_wsrf_core_get_resource_id_from_epr(
61             service_group_epr,
62             &resource_id);
63
64 16     if (result != GLOBUS_SUCCESS || resource_id == NULL)
65     {
66 0         result = GLOBUS_SERVICE_GROUP_UNKNOWN();
67         
68 0         goto out;
69     }
70
71 16     GlobusServiceGroupGlobalLock();
72 16     sg = globus_hashtable_remove(
73                 &globus_i_service_groups,
74                 resource_id);
75 16     if (sg == NULL)
76     {
77 2         result = GLOBUS_SERVICE_GROUP_UNKNOWN();
78
79 2         goto unlock_out;
80     }
81 14     GlobusServiceGroupGlobalUnlock();
82
83 14     globus_i_service_group_destroy(sg);
84
85 14     GlobusServiceGroupDebugExit();
86 14     return GLOBUS_SUCCESS;
87
88 unlock_out:
89 2     GlobusServiceGroupGlobalUnlock();
90 2     free(resource_id);
91 out:
92 3     GlobusServiceGroupDebugExit();
93 3     return result;
94 }
95 /* globus_service_group_destroy() */
96
97 #ifndef GLOBUS_DONT_DOCUMENT_INTERNAL
98 /**
99  * Destroy the state associated with a service group
100  * @ingroup wssg
101  * Destroys the internal state associated with the service group. All private
102  * data related to the group and the entries which are contained by the group
103  * is freed. This must be called after the group is no longer in the global
104  * list of service groups.
105  *
106  * @param sg
107  *     Service group to destroy.
108  */
109 void
110 globus_i_service_group_destroy(
111     globus_wsrf_service_group_t         sg)
112 15 {
113 15     globus_list_t *                     entries = NULL;
114 15     globus_list_t *                     tmp_entries = NULL;
115 15     globus_wsrf_service_group_entry_t   tmp;
116 15     globus_resource_t                   resource;
117 15     globus_result_t                     result;
118 15     GlobusFuncName(globus_i_service_group_destroy);
119
120 15     GlobusServiceGroupDebugEnter();
121     /* Destroy service group state */
122 15     GlobusServiceGroupLock(sg);
123 15     globus_hashtable_to_list(&sg->entries, &entries);
124 15     tmp_entries = entries;
125
126 40     while (! globus_list_empty(tmp_entries))
127     {
128 25         tmp = globus_list_first(tmp_entries);
129 25         tmp_entries = globus_list_rest(tmp_entries);
130 25         globus_hashtable_remove(&sg->entries, tmp->resource_id);
131     }
132 15     globus_hashtable_destroy(&sg->entries);
133 15     GlobusServiceGroupUnlock(sg);
134 15     globus_mutex_destroy(&sg->lock);
135
136 15     wsa_EndpointReferenceType_destroy_contents(&sg->service_group_epr);
137 15     wsa_AttributedURI_destroy_contents(&sg->service_group_entry_uri);
138 15     free(sg->service_group_entry_path);
139 15     free(sg->resource_id);
140 15     free(sg);
141
142     /* Destroy related service group entries */
143 40     while (!globus_list_empty(entries))
144     {
145 25         tmp = globus_list_remove(&entries, entries);
146
147         /* The resource may possibly not exist if scheduled termination
148          * occurred. In this case, we will still free the entry's data as the
149          * resource termination thread was unable to get to it before it was
150          * removed from the resource hashtable above.
151          */
152 25         result = globus_resource_find(tmp->resource_id, &resource);
153
154 25         if (result == GLOBUS_SUCCESS)
155         {
156 25             globus_resource_destroy(resource);
157         }
158 25         free(tmp->resource_id);
159 25         wssg_EntryType_destroy(tmp->entry);
160 25         free(tmp);
161     }
162 15     GlobusServiceGroupDebugExit();
163 }
164 /* globus_i_service_group_destroy() */