... | ... |
@@ -130,12 +130,16 @@ fprintf(stderr,"bg_get: \"%s\"\n",bgload->path); |
130 | 130 |
} |
131 | 131 |
|
132 | 132 |
int |
133 |
-bg_add(bg_t *bg, char *path) |
|
133 |
+bg_add(bg_t *bg, char *path, int flag_pinned) |
|
134 | 134 |
{ |
135 | 135 |
int i; |
136 | 136 |
bgload_t *bgload; |
137 | 137 |
if(bg==NULL) |
138 | 138 |
return(-1); |
139 |
+ if(path!=NULL && flag_pinned) { |
|
140 |
+ memset(bg->pinnedpath,0,sizeof(bg->pinnedpath)); |
|
141 |
+ strncpy(bg->pinnedpath,path,sizeof(bg->pinnedpath)-1); |
|
142 |
+ } |
|
139 | 143 |
for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
140 | 144 |
if(bgload->lended_to_thread && strcmp(path,bgload->path)==0) { |
141 | 145 |
bgload->is_todo=1; |
... | ... |
@@ -170,7 +174,11 @@ bg_freeunmarked(bg_t *bg) |
170 | 174 |
now=time(NULL); |
171 | 175 |
for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
172 | 176 |
if(bgload->lended_to_thread && bgload->thread_finished && bgload->has_mark==0) { |
173 |
- if(bgload->has_data && (bgload->lastused<(now-UNLOADTIMEOUTSECONDS) || bgload->lastused>(now+UNLOADTIMEOUTSECONDS))) { |
|
177 |
+ if(bgload->has_data |
|
178 |
+ && (bgload->lastused<(now-UNLOADTIMEOUTSECONDS) |
|
179 |
+ || bgload->lastused>(now+UNLOADTIMEOUTSECONDS)) |
|
180 |
+ && strcmp(bgload->path,bg->pinnedpath)!=0 |
|
181 |
+ ) { |
|
174 | 182 |
#if 1 |
175 | 183 |
fprintf(stderr,"bg: Unloading: \"%s\"\n",bgload->path); |
176 | 184 |
#endif |
... | ... |
@@ -16,6 +16,7 @@ |
16 | 16 |
#include <unistd.h> |
17 | 17 |
#include <string.h> |
18 | 18 |
#include <pthread.h> |
19 |
+#include <sys/time.h> |
|
19 | 20 |
#if !defined(__linux__) && !defined(ANDROID) |
20 | 21 |
#include "win32_pipe.h" |
21 | 22 |
#endif |
... | ... |
@@ -25,25 +26,20 @@ |
25 | 26 |
#include "bg.h" |
26 | 27 |
|
27 | 28 |
#define UNLOADTIMEOUTSECONDS 10 |
29 |
+#define THREADNUMBER 8 |
|
28 | 30 |
|
29 |
-static int mypipe(int fds[2]); |
|
30 |
-static int mypiperead(int fd, char *buf, int count); |
|
31 |
-static int mypipewrite(int fd, char *buf, int count); |
|
31 |
+static int mysleep(struct timeval *tv); |
|
32 | 32 |
|
33 | 33 |
void |
34 | 34 |
bg_staticinit(void) |
35 | 35 |
{ |
36 |
-#if !defined(__linux__) && !defined(ANDROID) |
|
37 |
- win32pipe_init(); |
|
38 |
-#endif |
|
36 |
+ /* not needed now, was for win32pipe_init() */ |
|
39 | 37 |
} |
40 | 38 |
|
41 | 39 |
void |
42 | 40 |
bg_staticfini(void) |
43 | 41 |
{ |
44 |
-#if !defined(__linux__) && !defined(ANDROID) |
|
45 |
- win32pipe_fini(); |
|
46 |
-#endif |
|
42 |
+ /* not needed now, was for win32pipe_fini() */ |
|
47 | 43 |
} |
48 | 44 |
|
49 | 45 |
bg_t * |
... | ... |
@@ -54,9 +50,6 @@ bg_init(int sizebgload) |
54 | 50 |
bg=NULL; |
55 | 51 |
if((errstr="Insuf. mem. for bg")==NULL |
56 | 52 |
|| (bg=calloc(1,sizeof(bg_t)))==NULL |
57 |
- || (errstr="Error init pipes (please check program is not blocked in firewall)")==NULL |
|
58 |
- || (bg->pipe[0]=bg->pipe[1]=-1)!=-1 |
|
59 |
- || mypipe(bg->pipe)!=0 |
|
60 | 53 |
|| (errstr="Insuf mem bgload")==NULL |
61 | 54 |
|| (bg->bgload=calloc(sizebgload,sizeof(bgload_t)))==NULL |
62 | 55 |
|| (bg->sizebgload=sizebgload)!=sizebgload |
... | ... |
@@ -81,11 +74,7 @@ bg_free(bg_t *bg) |
81 | 74 |
if(bg==NULL) |
82 | 75 |
return; /* nothing to do */ |
83 | 76 |
if(bg->flag_threadstarted) { |
84 |
- char dummy=1; |
|
85 |
-#if 1 |
|
86 |
-fprintf(stderr,"bg_free: notifying thread to exit\n"); |
|
87 |
-#endif |
|
88 |
- mypipewrite(bg->pipe[WR],&dummy,1); |
|
77 |
+ bg->do_exit=1; |
|
89 | 78 |
#if 1 |
90 | 79 |
fprintf(stderr,"bg_free: joining thread\n"); |
91 | 80 |
#endif |
... | ... |
@@ -94,11 +83,8 @@ fprintf(stderr,"bg_free: joining thread\n"); |
94 | 83 |
fprintf(stderr,"bg_free: thread joined OK\n"); |
95 | 84 |
#endif |
96 | 85 |
bg->flag_threadstarted=0; |
86 |
+ bg->do_exit=0; |
|
97 | 87 |
} |
98 |
- if(bg->pipe[0]!=-1) |
|
99 |
- close(bg->pipe[0]),bg->pipe[0]=-1; |
|
100 |
- if(bg->pipe[1]!=-1) |
|
101 |
- close(bg->pipe[1]),bg->pipe[1]=-1; |
|
102 | 88 |
if(bg->bgload!=NULL) { |
103 | 89 |
bgload_t *bgload; |
104 | 90 |
for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
... | ... |
@@ -148,7 +134,6 @@ bg_add(bg_t *bg, char *path) |
148 | 134 |
{ |
149 | 135 |
int i; |
150 | 136 |
bgload_t *bgload; |
151 |
- char dummy; |
|
152 | 137 |
if(bg==NULL) |
153 | 138 |
return(-1); |
154 | 139 |
for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
... | ... |
@@ -156,8 +141,6 @@ bg_add(bg_t *bg, char *path) |
156 | 141 |
bgload->is_todo=1; |
157 | 142 |
bgload->has_mark=1; |
158 | 143 |
gettimeofday(&(bgload->tv_lastadded),NULL); // Breaks premise of "don't touch until thread finished", but this is rather innocuous |
159 |
- dummy=0; |
|
160 |
- mypipewrite(bg->pipe[WR],&dummy,1); |
|
161 | 144 |
return(0); /* already on list */ |
162 | 145 |
} |
163 | 146 |
} |
... | ... |
@@ -169,9 +152,7 @@ bg_add(bg_t *bg, char *path) |
169 | 152 |
bgload->is_todo=1; |
170 | 153 |
bgload->has_mark=1; |
171 | 154 |
gettimeofday(&(bgload->tv_lastadded),NULL); // Breaks premise of "don't touch until thread finished", but this is rather innocuous |
172 |
- dummy=0; |
|
173 | 155 |
bgload->lended_to_thread=1; |
174 |
- mypipewrite(bg->pipe[WR],&dummy,1); |
|
175 | 156 |
return(0); /* added to list */ |
176 | 157 |
} |
177 | 158 |
} |
... | ... |
@@ -213,16 +194,11 @@ void * |
213 | 194 |
bg_thread(void *parambg) |
214 | 195 |
{ |
215 | 196 |
bg_t *bg; |
216 |
- char dummy; |
|
217 | 197 |
bg=(bg_t *)parambg; |
218 | 198 |
int i; |
219 | 199 |
bgload_t *bgload,*candidate; |
220 | 200 |
while(1) { |
221 |
- mypiperead(bg->pipe[RD],&dummy,1); |
|
222 |
-#if 1 |
|
223 |
-fprintf(stderr,"Thread received byte: %i\n",(int)((unsigned char)dummy)); |
|
224 |
-#endif |
|
225 |
- if(dummy!=0) |
|
201 |
+ if(bg->do_exit!=0) |
|
226 | 202 |
break; /* was told to exit */ |
227 | 203 |
for(candidate=NULL,i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
228 | 204 |
if(bgload->lended_to_thread==0) |
... | ... |
@@ -249,53 +225,35 @@ fprintf(stderr,"Thread received byte: %i\n",(int)((unsigned char)dummy)); |
249 | 225 |
bgload->has_failedload=1; |
250 | 226 |
bgload->lastused=time(NULL); |
251 | 227 |
bgload->thread_finished=1; |
228 |
+ } else { |
|
229 |
+ struct timeval tv; |
|
230 |
+ tv.tv_sec=0,tv.tv_usec=50*1000; /* sleep 50ms if nothing to do */ |
|
231 |
+ mysleep(&tv); |
|
252 | 232 |
} |
233 |
+#if 1 |
|
234 |
+fprintf(stderr,"."),fflush(stderr); |
|
235 |
+#endif |
|
253 | 236 |
} |
254 | 237 |
pthread_exit(NULL); |
255 | 238 |
return(NULL); |
256 | 239 |
} |
257 | 240 |
|
258 |
- |
|
259 |
- |
|
260 | 241 |
#if !defined(__linux__) && !defined(ANDROID) |
261 | 242 |
static int |
262 |
-mypipe(int fds[2]) |
|
263 |
-{ |
|
264 |
- return(win32pipe_pipe(fds)); |
|
265 |
-} |
|
266 |
- |
|
267 |
-static int |
|
268 |
-mypiperead(int fd, char *buf, int count) |
|
269 |
-{ |
|
270 |
- return(win32pipe_read(fd,buf,count)); |
|
271 |
-} |
|
272 |
- |
|
273 |
-static int |
|
274 |
-mypipewrite(int fd, char *buf, int count) |
|
243 |
+mysleep(struct timeval *tv) |
|
275 | 244 |
{ |
276 |
- return(win32pipe_write(fd,buf,count)); |
|
245 |
+ win32pipe_sleep(tv->tv_sec*1000+tv->tv_usec/1000); |
|
246 |
+ return(0); |
|
277 | 247 |
} |
278 | 248 |
#else |
279 | 249 |
static int |
280 |
-mypipe(int fds[2]) |
|
281 |
-{ |
|
282 |
- return(pipe(fds)); |
|
283 |
-} |
|
284 |
- |
|
285 |
-static int |
|
286 |
-mypiperead(int fd, char *buf, int count) |
|
287 |
-{ |
|
288 |
- return(read(fd,buf,count)); |
|
289 |
-} |
|
290 |
- |
|
291 |
-static int |
|
292 |
-mypipewrite(int fd, char *buf, int count) |
|
250 |
+mysleep(struct timeval *tv) |
|
293 | 251 |
{ |
294 |
- return(write(fd,buf,count)); |
|
252 |
+ struct timespec ts; |
|
253 |
+ if(tv==NULL) |
|
254 |
+ return(-1); |
|
255 |
+ ts.tv_sec=tv->tv_sec,ts.tv_nsec=tv->tv_usec*1000; |
|
256 |
+ nanosleep(&ts,NULL); |
|
257 |
+ return(0); |
|
295 | 258 |
} |
296 | 259 |
#endif |
297 |
- |
|
298 |
- |
|
299 |
- |
|
300 |
- |
|
301 |
- |
... | ... |
@@ -24,6 +24,8 @@ |
24 | 24 |
#include "rayui.h" |
25 | 25 |
#include "bg.h" |
26 | 26 |
|
27 |
+#define UNLOADTIMEOUTSECONDS 10 |
|
28 |
+ |
|
27 | 29 |
static int mypipe(int fds[2]); |
28 | 30 |
static int mypiperead(int fd, char *buf, int count); |
29 | 31 |
static int mypipewrite(int fd, char *buf, int count); |
... | ... |
@@ -153,6 +155,7 @@ bg_add(bg_t *bg, char *path) |
153 | 155 |
if(bgload->lended_to_thread && strcmp(path,bgload->path)==0) { |
154 | 156 |
bgload->is_todo=1; |
155 | 157 |
bgload->has_mark=1; |
158 |
+ gettimeofday(&(bgload->tv_lastadded),NULL); // Breaks premise of "don't touch until thread finished", but this is rather innocuous |
|
156 | 159 |
dummy=0; |
157 | 160 |
mypipewrite(bg->pipe[WR],&dummy,1); |
158 | 161 |
return(0); /* already on list */ |
... | ... |
@@ -165,6 +168,7 @@ bg_add(bg_t *bg, char *path) |
165 | 168 |
bgload->path[sizeof(bgload->path)-1]='\0'; |
166 | 169 |
bgload->is_todo=1; |
167 | 170 |
bgload->has_mark=1; |
171 |
+ gettimeofday(&(bgload->tv_lastadded),NULL); // Breaks premise of "don't touch until thread finished", but this is rather innocuous |
|
168 | 172 |
dummy=0; |
169 | 173 |
bgload->lended_to_thread=1; |
170 | 174 |
mypipewrite(bg->pipe[WR],&dummy,1); |
... | ... |
@@ -179,11 +183,13 @@ bg_freeunmarked(bg_t *bg) |
179 | 183 |
{ |
180 | 184 |
int i; |
181 | 185 |
bgload_t *bgload; |
186 |
+ time_t now; |
|
182 | 187 |
if(bg==NULL) |
183 | 188 |
return(-1); |
189 |
+ now=time(NULL); |
|
184 | 190 |
for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
185 | 191 |
if(bgload->lended_to_thread && bgload->thread_finished && bgload->has_mark==0) { |
186 |
- if(bgload->has_data) { |
|
192 |
+ if(bgload->has_data && (bgload->lastused<(now-UNLOADTIMEOUTSECONDS) || bgload->lastused>(now+UNLOADTIMEOUTSECONDS))) { |
|
187 | 193 |
#if 1 |
188 | 194 |
fprintf(stderr,"bg: Unloading: \"%s\"\n",bgload->path); |
189 | 195 |
#endif |
... | ... |
@@ -196,6 +202,8 @@ fprintf(stderr,"bg: Cancelling: \"%s\"\n",bgload->path); |
196 | 202 |
} |
197 | 203 |
#endif |
198 | 204 |
memset(bgload,0,sizeof(bgload_t)); |
205 |
+ } else if(bgload->lended_to_thread && bgload->thread_finished && bgload->has_mark!=0 && bgload->has_data) { |
|
206 |
+ bgload->lastused=now; |
|
199 | 207 |
} |
200 | 208 |
} |
201 | 209 |
return(0); |
... | ... |
@@ -208,7 +216,7 @@ bg_thread(void *parambg) |
208 | 216 |
char dummy; |
209 | 217 |
bg=(bg_t *)parambg; |
210 | 218 |
int i; |
211 |
- bgload_t *bgload; |
|
219 |
+ bgload_t *bgload,*candidate; |
|
212 | 220 |
while(1) { |
213 | 221 |
mypiperead(bg->pipe[RD],&dummy,1); |
214 | 222 |
#if 1 |
... | ... |
@@ -216,7 +224,7 @@ fprintf(stderr,"Thread received byte: %i\n",(int)((unsigned char)dummy)); |
216 | 224 |
#endif |
217 | 225 |
if(dummy!=0) |
218 | 226 |
break; /* was told to exit */ |
219 |
- for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
227 |
+ for(candidate=NULL,i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
220 | 228 |
if(bgload->lended_to_thread==0) |
221 | 229 |
continue; |
222 | 230 |
if(bgload->is_todo==0) { |
... | ... |
@@ -224,14 +232,24 @@ fprintf(stderr,"Thread received byte: %i\n",(int)((unsigned char)dummy)); |
224 | 232 |
continue; |
225 | 233 |
} |
226 | 234 |
if(bgload->has_data==0 && bgload->has_failedload==0) { |
227 |
- bgload->image=global_loadimage(bgload->path); |
|
228 |
- if(IsImageValid(bgload->image)) |
|
229 |
- bgload->has_data=1; |
|
230 |
- else |
|
231 |
- bgload->has_failedload=1; |
|
232 |
- bgload->thread_finished=1; |
|
235 |
+ if(candidate==NULL |
|
236 |
+ || bgload->tv_lastadded.tv_sec>candidate->tv_lastadded.tv_sec |
|
237 |
+ || (bgload->tv_lastadded.tv_sec==candidate->tv_lastadded.tv_sec && bgload->tv_lastadded.tv_usec>candidate->tv_lastadded.tv_usec) |
|
238 |
+ ) { |
|
239 |
+ candidate=bgload; |
|
240 |
+ } |
|
233 | 241 |
} |
234 | 242 |
} |
243 |
+ if(candidate!=NULL) { |
|
244 |
+ bgload=candidate; |
|
245 |
+ bgload->image=global_loadimage(bgload->path); |
|
246 |
+ if(IsImageValid(bgload->image)) |
|
247 |
+ bgload->has_data=1; |
|
248 |
+ else |
|
249 |
+ bgload->has_failedload=1; |
|
250 |
+ bgload->lastused=time(NULL); |
|
251 |
+ bgload->thread_finished=1; |
|
252 |
+ } |
|
235 | 253 |
} |
236 | 254 |
pthread_exit(NULL); |
237 | 255 |
return(NULL); |
1 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,283 @@ |
1 |
+/* |
|
2 |
+ * bg.c |
|
3 |
+ * |
|
4 |
+ * Wrapper over pthread with the addition of some interthread comms. |
|
5 |
+ * |
|
6 |
+ * History: |
|
7 |
+ * 20250904 Creation from imgmover prototype. |
|
8 |
+ * |
|
9 |
+ * Author: Dario Rodriguez dario@darionomono.com |
|
10 |
+ * (c) Dario Rodriguez 2025 |
|
11 |
+ * This program is licensed under the terms of GNU GPL v2.1+ |
|
12 |
+ */ |
|
13 |
+ |
|
14 |
+#include <stdio.h> |
|
15 |
+#include <stdlib.h> |
|
16 |
+#include <unistd.h> |
|
17 |
+#include <string.h> |
|
18 |
+#include <pthread.h> |
|
19 |
+#if !defined(__linux__) && !defined(ANDROID) |
|
20 |
+#include "win32_pipe.h" |
|
21 |
+#endif |
|
22 |
+ |
|
23 |
+#include "raylib.h" |
|
24 |
+#include "rayui.h" |
|
25 |
+#include "bg.h" |
|
26 |
+ |
|
27 |
+static int mypipe(int fds[2]); |
|
28 |
+static int mypiperead(int fd, char *buf, int count); |
|
29 |
+static int mypipewrite(int fd, char *buf, int count); |
|
30 |
+ |
|
31 |
+void |
|
32 |
+bg_staticinit(void) |
|
33 |
+{ |
|
34 |
+#if !defined(__linux__) && !defined(ANDROID) |
|
35 |
+ win32pipe_init(); |
|
36 |
+#endif |
|
37 |
+} |
|
38 |
+ |
|
39 |
+void |
|
40 |
+bg_staticfini(void) |
|
41 |
+{ |
|
42 |
+#if !defined(__linux__) && !defined(ANDROID) |
|
43 |
+ win32pipe_fini(); |
|
44 |
+#endif |
|
45 |
+} |
|
46 |
+ |
|
47 |
+bg_t * |
|
48 |
+bg_init(int sizebgload) |
|
49 |
+{ |
|
50 |
+ bg_t *bg; |
|
51 |
+ char *errstr; |
|
52 |
+ bg=NULL; |
|
53 |
+ if((errstr="Insuf. mem. for bg")==NULL |
|
54 |
+ || (bg=calloc(1,sizeof(bg_t)))==NULL |
|
55 |
+ || (errstr="Error init pipes (please check program is not blocked in firewall)")==NULL |
|
56 |
+ || (bg->pipe[0]=bg->pipe[1]=-1)!=-1 |
|
57 |
+ || mypipe(bg->pipe)!=0 |
|
58 |
+ || (errstr="Insuf mem bgload")==NULL |
|
59 |
+ || (bg->bgload=calloc(sizebgload,sizeof(bgload_t)))==NULL |
|
60 |
+ || (bg->sizebgload=sizebgload)!=sizebgload |
|
61 |
+ || (errstr="pthread attr init error")==NULL |
|
62 |
+ || pthread_attr_init(&(bg->tattr))!=0 |
|
63 |
+ || (errstr="pthread create error")==NULL |
|
64 |
+ || pthread_create(&(bg->thread),&(bg->tattr),bg_thread,(void *)bg)!=0 |
|
65 |
+ || (bg->flag_threadstarted=1)!=1 |
|
66 |
+ ) { |
|
67 |
+ global_messagebox("%s",errstr); |
|
68 |
+ bg_free(bg); |
|
69 |
+ return(NULL); |
|
70 |
+ } |
|
71 |
+ return(bg); |
|
72 |
+} |
|
73 |
+ |
|
74 |
+ |
|
75 |
+void |
|
76 |
+bg_free(bg_t *bg) |
|
77 |
+{ |
|
78 |
+ int i; |
|
79 |
+ if(bg==NULL) |
|
80 |
+ return; /* nothing to do */ |
|
81 |
+ if(bg->flag_threadstarted) { |
|
82 |
+ char dummy=1; |
|
83 |
+#if 1 |
|
84 |
+fprintf(stderr,"bg_free: notifying thread to exit\n"); |
|
85 |
+#endif |
|
86 |
+ mypipewrite(bg->pipe[WR],&dummy,1); |
|
87 |
+#if 1 |
|
88 |
+fprintf(stderr,"bg_free: joining thread\n"); |
|
89 |
+#endif |
|
90 |
+ pthread_join(bg->thread,NULL); |
|
91 |
+#if 1 |
|
92 |
+fprintf(stderr,"bg_free: thread joined OK\n"); |
|
93 |
+#endif |
|
94 |
+ bg->flag_threadstarted=0; |
|
95 |
+ } |
|
96 |
+ if(bg->pipe[0]!=-1) |
|
97 |
+ close(bg->pipe[0]),bg->pipe[0]=-1; |
|
98 |
+ if(bg->pipe[1]!=-1) |
|
99 |
+ close(bg->pipe[1]),bg->pipe[1]=-1; |
|
100 |
+ if(bg->bgload!=NULL) { |
|
101 |
+ bgload_t *bgload; |
|
102 |
+ for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
103 |
+ if(bgload->has_data) { |
|
104 |
+ UnloadImage(bgload->image); |
|
105 |
+ bgload->has_data=0; |
|
106 |
+ } |
|
107 |
+ } |
|
108 |
+ free(bg->bgload),bg->bgload=NULL,bg->sizebgload=0; |
|
109 |
+ } |
|
110 |
+ return; |
|
111 |
+} |
|
112 |
+ |
|
113 |
+int |
|
114 |
+bg_resetmarks(bg_t *bg) |
|
115 |
+{ |
|
116 |
+ int i; |
|
117 |
+ bgload_t *bgload; |
|
118 |
+ if(bg==NULL) |
|
119 |
+ return(-1); |
|
120 |
+ for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) |
|
121 |
+ bgload->has_mark=0; |
|
122 |
+ return(0); |
|
123 |
+} |
|
124 |
+ |
|
125 |
+bgload_t * |
|
126 |
+bg_get(bg_t *bg, char *path) |
|
127 |
+{ |
|
128 |
+ int i; |
|
129 |
+ bgload_t *bgload; |
|
130 |
+ if(bg==NULL) |
|
131 |
+ return(NULL); |
|
132 |
+ for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
133 |
+ if(bgload->thread_finished && bgload->has_data && strcmp(path,bgload->path)==0) { |
|
134 |
+ bgload->has_mark=1; |
|
135 |
+#if 1 |
|
136 |
+fprintf(stderr,"bg_get: \"%s\"\n",bgload->path); |
|
137 |
+#endif |
|
138 |
+ return(bgload); |
|
139 |
+ } |
|
140 |
+ } |
|
141 |
+ return(NULL); |
|
142 |
+} |
|
143 |
+ |
|
144 |
+int |
|
145 |
+bg_add(bg_t *bg, char *path) |
|
146 |
+{ |
|
147 |
+ int i; |
|
148 |
+ bgload_t *bgload; |
|
149 |
+ char dummy; |
|
150 |
+ if(bg==NULL) |
|
151 |
+ return(-1); |
|
152 |
+ for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
153 |
+ if(bgload->lended_to_thread && strcmp(path,bgload->path)==0) { |
|
154 |
+ bgload->is_todo=1; |
|
155 |
+ bgload->has_mark=1; |
|
156 |
+ dummy=0; |
|
157 |
+ mypipewrite(bg->pipe[WR],&dummy,1); |
|
158 |
+ return(0); /* already on list */ |
|
159 |
+ } |
|
160 |
+ } |
|
161 |
+ for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
162 |
+ if(bgload->lended_to_thread==0) { |
|
163 |
+ memset(bgload,0,sizeof(bgload_t)); |
|
164 |
+ strncpy(bgload->path,path,sizeof(bgload->path)); |
|
165 |
+ bgload->path[sizeof(bgload->path)-1]='\0'; |
|
166 |
+ bgload->is_todo=1; |
|
167 |
+ bgload->has_mark=1; |
|
168 |
+ dummy=0; |
|
169 |
+ bgload->lended_to_thread=1; |
|
170 |
+ mypipewrite(bg->pipe[WR],&dummy,1); |
|
171 |
+ return(0); /* added to list */ |
|
172 |
+ } |
|
173 |
+ } |
|
174 |
+ return(-1); /* couldn't add */ |
|
175 |
+} |
|
176 |
+ |
|
177 |
+int |
|
178 |
+bg_freeunmarked(bg_t *bg) |
|
179 |
+{ |
|
180 |
+ int i; |
|
181 |
+ bgload_t *bgload; |
|
182 |
+ if(bg==NULL) |
|
183 |
+ return(-1); |
|
184 |
+ for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
185 |
+ if(bgload->lended_to_thread && bgload->thread_finished && bgload->has_mark==0) { |
|
186 |
+ if(bgload->has_data) { |
|
187 |
+#if 1 |
|
188 |
+fprintf(stderr,"bg: Unloading: \"%s\"\n",bgload->path); |
|
189 |
+#endif |
|
190 |
+ UnloadImage(bgload->image); |
|
191 |
+ bgload->has_data=0; |
|
192 |
+ } |
|
193 |
+#if 1 |
|
194 |
+else { |
|
195 |
+fprintf(stderr,"bg: Cancelling: \"%s\"\n",bgload->path); |
|
196 |
+} |
|
197 |
+#endif |
|
198 |
+ memset(bgload,0,sizeof(bgload_t)); |
|
199 |
+ } |
|
200 |
+ } |
|
201 |
+ return(0); |
|
202 |
+} |
|
203 |
+ |
|
204 |
+void * |
|
205 |
+bg_thread(void *parambg) |
|
206 |
+{ |
|
207 |
+ bg_t *bg; |
|
208 |
+ char dummy; |
|
209 |
+ bg=(bg_t *)parambg; |
|
210 |
+ int i; |
|
211 |
+ bgload_t *bgload; |
|
212 |
+ while(1) { |
|
213 |
+ mypiperead(bg->pipe[RD],&dummy,1); |
|
214 |
+#if 1 |
|
215 |
+fprintf(stderr,"Thread received byte: %i\n",(int)((unsigned char)dummy)); |
|
216 |
+#endif |
|
217 |
+ if(dummy!=0) |
|
218 |
+ break; /* was told to exit */ |
|
219 |
+ for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
220 |
+ if(bgload->lended_to_thread==0) |
|
221 |
+ continue; |
|
222 |
+ if(bgload->is_todo==0) { |
|
223 |
+ bgload->thread_finished=1; |
|
224 |
+ continue; |
|
225 |
+ } |
|
226 |
+ if(bgload->has_data==0 && bgload->has_failedload==0) { |
|
227 |
+ bgload->image=global_loadimage(bgload->path); |
|
228 |
+ if(IsImageValid(bgload->image)) |
|
229 |
+ bgload->has_data=1; |
|
230 |
+ else |
|
231 |
+ bgload->has_failedload=1; |
|
232 |
+ bgload->thread_finished=1; |
|
233 |
+ } |
|
234 |
+ } |
|
235 |
+ } |
|
236 |
+ pthread_exit(NULL); |
|
237 |
+ return(NULL); |
|
238 |
+} |
|
239 |
+ |
|
240 |
+ |
|
241 |
+ |
|
242 |
+#if !defined(__linux__) && !defined(ANDROID) |
|
243 |
+static int |
|
244 |
+mypipe(int fds[2]) |
|
245 |
+{ |
|
246 |
+ return(win32pipe_pipe(fds)); |
|
247 |
+} |
|
248 |
+ |
|
249 |
+static int |
|
250 |
+mypiperead(int fd, char *buf, int count) |
|
251 |
+{ |
|
252 |
+ return(win32pipe_read(fd,buf,count)); |
|
253 |
+} |
|
254 |
+ |
|
255 |
+static int |
|
256 |
+mypipewrite(int fd, char *buf, int count) |
|
257 |
+{ |
|
258 |
+ return(win32pipe_write(fd,buf,count)); |
|
259 |
+} |
|
260 |
+#else |
|
261 |
+static int |
|
262 |
+mypipe(int fds[2]) |
|
263 |
+{ |
|
264 |
+ return(pipe(fds)); |
|
265 |
+} |
|
266 |
+ |
|
267 |
+static int |
|
268 |
+mypiperead(int fd, char *buf, int count) |
|
269 |
+{ |
|
270 |
+ return(read(fd,buf,count)); |
|
271 |
+} |
|
272 |
+ |
|
273 |
+static int |
|
274 |
+mypipewrite(int fd, char *buf, int count) |
|
275 |
+{ |
|
276 |
+ return(write(fd,buf,count)); |
|
277 |
+} |
|
278 |
+#endif |
|
279 |
+ |
|
280 |
+ |
|
281 |
+ |
|
282 |
+ |
|
283 |
+ |