design_pattern_for_c  V 1.00
director.c
Go to the documentation of this file.
1 
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <pthread.h>
9 #include <dlfcn.h>
10 #include "builder_action.h"
11 #include "director.h"
12 #include "dp_debug.h"
13 
14 /*************
15  * public define
16 *************/
17 #define LLD_METHODSIZE_MAX (64)
18 
22 struct director_t {
23  //public
24  pthread_t tid;
26  int (** builder_methods)(void * initial_parameter);
27  //private
28  void * dlhandle;
29  void * (*builder_instance_new)(void);
30  void (*builder_instance_free)(void *interface);
31 };
32 
34 /* @{ */
35 static int director_open_library(Director this, char * builder_lib_name);
36 static int director_load_methods(char * conffile, char ***methodname);
37 static void director_free_methods(int methodcnt, char **methodname);
38 static int director_add_methods(Director this, int methodcnt, char **methodname);
40 /* @} */
41 
42 /*************
43  * for Director private method
44 *************/
46 /* @{ */
47 static int director_open_library(Director this, char * builder_lib_name) {
48  //load library
49  void * handle = dlopen(builder_lib_name, RTLD_NOW);
50  if(!handle) {
51  DEBUG_ERRPRINT("failed to open library %s\n", builder_lib_name);
52  return LL_BUILDER_FAILED;
53  }
54  this->dlhandle = handle;
55  return LL_BUILDER_SUCCESS;
56 }
57 
58 static int director_load_methods(char * conffile, char ***methodname) {
59  int ret_num=0;
60  FILE *fp = fopen(conffile, "r");
61  if(!fp) {
62  DEBUG_ERRPRINT("failed to open file %s\n", conffile);
63  return LL_BUILDER_FAILED;
64  }
65 
66  //count max line
67  int line=0;
68  char buffer[LLD_METHODSIZE_MAX];
69  while(fgets(buffer, sizeof(buffer), fp) != NULL) {
70  line++;
71  }
72  //goto head
73  fseek(fp, 0, SEEK_SET);
74 
75  //allocate
76  *methodname = (char **) calloc(line, sizeof(char *));
77  if(!*methodname) {
78  goto err;
79  }
80 
81  //read conf
82  while(fgets(buffer, sizeof(buffer), fp) != NULL) {
83  //skip comment
84  if(buffer[0]=='#') {
85  DEBUG_ERRPRINT("continue comment\n");
86  continue;
87  }
88 
89  //allocate memory
90  (*methodname)[ret_num] = calloc(1, LLD_METHODSIZE_MAX);
91  if(!methodname[ret_num]) {
92  goto err;
93  }
94 
95  //clear after comment
96  char *after_comment = strstr(buffer, "/");
97  if(after_comment) {
98  *after_comment = 0;
99  }
100 
101  snprintf((*methodname)[ret_num++], LLD_METHODSIZE_MAX, "%s", buffer);
102  }
103  fclose(fp);
104  return ret_num;
105 err:
106  fclose(fp);
107  director_free_methods(ret_num, *methodname);
108  return LL_BUILDER_FAILED;
109 }
110 
111 static void director_free_methods(int methodcnt, char **methodname) {
112  if(!methodname) {
113  return;
114  }
115 
116  int i=0;
117  for(i = 0; i < methodcnt; i ++ ) {
118  free(methodname[i]);
119  }
120  free(methodname);
121 }
122 
123 static int director_add_methods(Director this, int methodcnt, char **methodname) {
124  this->builder_methods = calloc(methodcnt, sizeof(void (*)(void *)));
125  if(!this->builder_methods) {
126  return LL_BUILDER_FAILED;
127  }
128 
129  int i=0;
130  for( i = 0; i < methodcnt; i ++ ) {
131  //don't care NULL
132  this->builder_methods[i] = dlsym(this->dlhandle, methodname[i]);
133  if(!this->builder_methods) {
134  DEBUG_ERRPRINT("library API %s is not implement, error detail =%s\n", methodname[i], dlerror());
135  }
136  }
137  this->builder_method_cnt = methodcnt;
138  return LL_BUILDER_SUCCESS;
139 }
140 
142  this->builder_instance_new = dlsym(this->dlhandle, LL_BUILDER_NEWNAME);
143  if( this->builder_instance_new ) {
144  this->builder_instance_free = dlsym(this->dlhandle, LL_BUILDER_FREENAME);
145  }
146 }
147 
148 /* @} */
149 
151 /* @{ */
152 Director director_new(char * builder_lib_name, char * builder_interface_conf) {
153  int ret = LL_BUILDER_FAILED;
154  int methodcnt;
155  char **methodnames=NULL;
156 
157  Director instance = (Director) calloc(1, sizeof(*instance));
158  if(!instance) {
159  DEBUG_ERRPRINT("failed to calloc\n");
160  return NULL;
161  }
162 
163  //load library
164  ret = director_open_library(instance, builder_lib_name);
165  if( ret == LL_BUILDER_FAILED ) {
166  DEBUG_ERRPRINT("failed to open library\n");
167  goto err;
168  }
169 
170  //get methods name from conf
171  methodcnt = director_load_methods(builder_interface_conf, &methodnames);
172  if( methodcnt == LL_BUILDER_FAILED ) {
173  DEBUG_ERRPRINT("failed to load methods conf %s\n", builder_interface_conf);
174  goto err;
175  }
176 
177  //load library method in conf
178  ret = director_add_methods(instance, methodcnt, methodnames);
179  //free local memory
180  director_free_methods(methodcnt, methodnames);
181  if( ret == LL_BUILDER_FAILED ) {
182  DEBUG_ERRPRINT("failed to load methods conf %s\n", builder_interface_conf);
183  goto err;
184  }
185 
186  //load common library
188  return instance;
189 
190 err:
191  director_free(instance);
192  return NULL;
193 }
194 
195 void director_construct(Director director, void * initial_parameter, void (*initial_result)(int result)) {
196 
197  builder_action_parameter_t parameter;
198  parameter.initial_parameter = initial_parameter;
199  parameter.initial_result = initial_result;
200  parameter.builder_method_cnt = director->builder_method_cnt;
201  parameter.builder_methods = director->builder_methods;
202 
203  director->tid = builder_action_construct(&parameter);
204 }
205 
206 void director_destruct(Director director) {
207  //to care constructing now
208  builder_action_destruct(director->tid);
209 }
210 
212  if(!this || !this->builder_instance_new) {
213  DEBUG_ERRPRINT("No interface\n");
214  return NULL;
215  }
216 
217  return this->builder_instance_new();
218 }
219 
220 void director_interface_class_free(Director this, void * instance) {
221  if(!instance || !this->builder_instance_free) {
222  DEBUG_ERRPRINT("No interface\n");
223  return;
224  }
225 
226  this->builder_instance_free(instance);
227 }
228 
230  if(!this) {
231  return;
232  }
233 
234  //free instance
235  free(this->builder_methods);
236 
237  //close library
238  if(this->dlhandle) {
239  if(dlclose(this->dlhandle)) {
240  DEBUG_ERRPRINT("failed to unload library\n");
241  }
242  }
243 
244  free(this);
245 }
246 /* @} */
#define LL_BUILDER_FAILED
result code : error
This is API definition of builder action API.
int(** builder_methods)(void *initial_parameter)
Definition: director.c:26
Director director_new(char *builder_lib_name, char *builder_interface_conf)
director new
Definition: director.c:152
static void director_load_interface_method(Director this)
Definition: director.c:141
static int director_load_methods(char *conffile, char ***methodname)
Definition: director.c:58
pthread_t tid
Definition: director.c:24
void(* initial_result)(int result)
void(* free)(EventInstance this)
Definition: event_thread.c:39
#define LL_BUILDER_SUCCESS
result code : success
void director_interface_class_free(Director this, void *instance)
interface class free
Definition: director.c:220
This is API definition of Director class.
static int director_open_library(Director this, char *builder_lib_name)
Definition: director.c:47
void * handle
Definition: event_thread.c:30
int builder_method_cnt
Definition: director.c:25
director class
void builder_action_destruct(pthread_t tid)
deconstruct action
#define LLD_METHODSIZE_MAX
Definition: director.c:17
static void director_free_methods(int methodcnt, char **methodname)
Definition: director.c:111
#define LL_BUILDER_NEWNAME
name definition of plugin interface "new"
#define LL_BUILDER_FREENAME
name definition of plugin interface "free"
For using debug log.
pthread_t builder_action_construct(builder_action_parameter_t *parameter)
construct action
void director_construct(Director director, void *initial_parameter, void(*initial_result)(int result))
director construct
Definition: director.c:195
static int director_add_methods(Director this, int methodcnt, char **methodname)
Definition: director.c:123
director class member definition
Definition: director.c:22
void(* builder_instance_free)(void *interface)
Definition: director.c:30
builder action parameter
void * director_interface_class_new(Director this)
interface class new
Definition: director.c:211
#define DEBUG_ERRPRINT(...)
Definition: dp_debug.h:69
void director_free(Director this)
director free
Definition: director.c:229
void * dlhandle
Definition: director.c:28
struct director_t * Director
Typedef class Director, member is defined in struct director_t.
int(** builder_methods)(void *initial_parameter)
void director_destruct(Director director)
director destruct
Definition: director.c:206