125 #include <system_threads.h>
126 #include <resources.h>
127 #include <libFreeWRL.h>
128 #include <internal.h>
130 #include "main/MainLoop.h"
134 void startNewHTMLWindow(
char *url);
136 void launch_in_web_browser(
void *res){
138 url = fwl_resitem_getURL(res);
141 startNewHTMLWindow(url);
151 bool resource_fetch(
void *res)
156 DEBUG_RES(
"fetching resource: %s, %s resource %s\n", resourceTypeToString(res->type), resourceStatusToString(res->status) ,res->URLrequest);
159 type = fwl_resitem_getType(res);
160 url = fwl_resitem_getURL(res);
161 status = fwl_resitem_getStatus(res);
168 ERROR_MSG(
"resource_fetch: can't fetch an invalid resource: %s\n", url);
169 fwl_resitem_setStatus(res,ress_invalid);
175 case ress_starts_good:
176 DEBUG_RES (
"resource_fetch, calling download_url\n");
195 status = fwl_resitem_getStatus(res);
198 case ress_starts_good:
199 if (do_file_exists(url)){
200 if (do_file_readable(url)){
202 fwl_resitem_setStatus(res,ress_downloaded);
204 fwl_resitem_setActualFile(res,url);
207 fwl_resitem_setStatus(res,ress_failed);
208 ERROR_MSG(
"resource_fetch: wrong permission to read file: %s\n", url);
212 fwl_resitem_setStatus(res,ress_failed);
230 DEBUG_RES (
"resource_fetch (end): network=%s type=%s status=%s"
231 " request=<%s> base=<%s> url=<%s> [parent %p, %s]\n",
232 BOOL_STR(res->network), resourceTypeToString(res->type),
233 resourceStatusToString(res->status), res->URLrequest,
234 res->URLbase, res->parsed_request,
235 res->parent, (res->parent ? res->parent->URLbase :
"N/A"));
237 return fwl_resitem_getStatus(res) == ress_downloaded;
241 void frontenditem_enqueue_tg(
s_list_t *item,
void *tg);
242 s_list_t *frontenditem_dequeue_tg(
void *tg);
245 int checkReplaceWorldRequest();
246 int checkExitRequest();
250 } url2file_task_tactic;
253 file2blob_task_chain,
254 file2blob_task_spawn,
255 file2blob_task_enqueue,
256 } file2blob_task_tactic;
260 int url2file(
void *res){
261 int status, retval = 0;
263 status = fwl_resitem_getStatus(res);
264 if(status == ress_downloaded){
271 void file2blob_task(
s_list_t *item);
272 extern int async_thread_count;
273 static void *thread_download_async (
void *args){
278 void *res = (
void*)item->elem;
279 async_thread_count++;
281 tg = fwl_resitem_getGlobal(res);
282 if(fwl_setCurrentHandle(tg, __FILE__, __LINE__));
284 downloaded = url2file(res);
288 file2blob_task(item);
290 resitem_enqueue(item);
292 async_thread_count--;
295 void downloadAsync (
s_list_t *item) {
297 void *res = (
void *)item->elem;
299 thread = fwl_resitem_getDownloadThread(res);
301 if(!thread) thread = malloc(
sizeof(pthread_t));
303 fwl_resitem_setDownloadThread(res,thread);
304 pthread_create (thread, NULL,&thread_download_async, (
void *)item);
310 #define MAX_SPAWNED_PER_PASS 15 //in desktop I've had 57 spawned threads at once, with no problems. In case there's a problem this will limit spawned-per-pass, which will indirectly limit spawned-at-same-time
311 void frontend_dequeue_get_enqueue(
void *tg){
315 fwl_setCurrentHandle(tg, __FILE__, __LINE__);
317 while( max(count_this_pass,async_thread_count) < MAX_SPAWNED_PER_PASS && !checkExitRequest() && !checkReplaceWorldRequest() && (item = frontenditem_dequeue()) != NULL ){
321 if(fwl_resitem_getStatus(res) != ress_downloaded){
322 int tactic = url2file_task_spawn;
323 if(fwl_resitem_getMediaType(res) == resm_external){
325 launch_in_web_browser(res);
326 fwl_resitem_setStatus(res,ress_none);
327 resitem_enqueue(item);
329 if(tactic == url2file_task_chain){
334 resitem_enqueue(item);
348 }
else if(tactic == url2file_task_spawn){
353 if(fwl_resitem_getStatus(res) == ress_downloaded){
354 file2blob_task(item);
361 void SSR_reply(
void * tg);
362 void dequeue_SSR_request(
void * tg);
364 char *get_key_val(
char *
key);
365 void _displayThread(
void *globalcontext)
388 fwl_setCurrentHandle(globalcontext, __FILE__, __LINE__);
389 ENTER_THREAD(
"display");
393 char *running_ssr = get_key_val(
"SSR");
395 if(!strcmp(running_ssr,
"true"))
404 SSR_reply(globalcontext);
405 dequeue_SSR_request(globalcontext);
416 frontend_dequeue_get_enqueue(globalcontext);
420 if(0) FW_GL_SWAPBUFFERS;
430 void fwl_initializeDisplayThread()
438 ASSERT(TEST_NULL_THREAD(gglobal()->threads.DispThrd));
450 ret = pthread_create(&tg->threads.DispThrd, NULL, (
void *) _displayThread, tg);
455 ERROR_MSG(
"initializeDisplayThread: not enough system resources to create a process for the new thread.");
461 #if !defined(_MSC_VER)
462 if (gglobal()->internalc.global_trace_threads) {
463 TRACE_MSG(
"initializeDisplayThread: waiting for display to become initialized...\n");
464 while (IS_DISPLAY_INITIALIZED == FALSE) {
475 void fwl_spawnRenderingThread(
void *globalcontext){
480 fwl_initializeDisplayThread();
489 void fwl_startFreeWRL(
const char *url)
503 fwl_resource_push_single_request(url);
504 DEBUG_MSG(
"request sent to parser thread, main thread joining display thread...\n");
506 DEBUG_MSG(
"no request for parser thread, main thread joining display thread...\n");