comparison dmres.c @ 359:59045853853d

Make resource management re-entrant.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 16 Oct 2012 21:25:46 +0300
parents 6d9d43bb68eb
children a0160ffdf7e5
comparison
equal deleted inserted replaced
358:3bdc776a4b33 359:59045853853d
6 */ 6 */
7 #include "dmres.h" 7 #include "dmres.h"
8 #include <time.h> 8 #include <time.h>
9 9
10 10
11 #define DMRES_LOCK(x) dmMutexLock(dfResourcesMutex) 11 DMResource *dmres_new(DMResourceLib *lib, const char *filename, int flags, size_t size)
12 #define DMRES_UNLOCK(x) dmMutexUnlock(dfResourcesMutex)
13
14
15 /* Global variables
16 */
17 static BOOL dfResInitialized = FALSE;
18 static int dfResFlags = 0;
19 static char * dfResPath = NULL;
20 DMResource * dfResources = NULL;
21 DMMutex * dfResourcesMutex = NULL;
22
23
24 #ifdef DM_USE_PACKFS
25 static DMPackFile *dfResPackFile = NULL;
26 static char * dfResPackFilename = NULL;
27 #endif
28
29
30 DMResource *dmres_new(const char *filename, int flags, size_t size)
31 { 12 {
32 DMResource *node = dmMalloc0(sizeof(DMResource)); 13 DMResource *node = dmMalloc0(sizeof(DMResource));
33 if (node == NULL) 14 if (node == NULL)
34 return NULL; 15 return NULL;
35 16
17 node->lib = lib;
36 node->filename = dm_strdup(filename); 18 node->filename = dm_strdup(filename);
37 node->flags = flags; 19 node->flags = flags;
38 node->dataSize = size; 20 node->dataSize = size;
39 21
40 return node; 22 return node;
82 dmFree(node); 64 dmFree(node);
83 } 65 }
84 } 66 }
85 67
86 68
87 static void dmres_insert(DMResource * node) 69 void dmres_insert(DMResourceLib *lib, DMResource * node)
88 { 70 {
89 if (dfResources != NULL) 71 if (lib == NULL)
90 { 72 return;
91 node->prev = dfResources->prev; 73
92 dfResources->prev->next = node; 74 node->lib = lib;
93 dfResources->prev = node; 75
76 if (lib->resources != NULL)
77 {
78 node->prev = lib->resources->prev;
79 lib->resources->prev->next = node;
80 lib->resources->prev = node;
94 } 81 }
95 else 82 else
96 { 83 {
97 dfResources = node->prev = node; 84 lib->resources = node->prev = node;
98 } 85 }
99 86
100 node->next = NULL; 87 node->next = NULL;
101 } 88 }
102 89
103 90
104 static void dmres_delete(DMResource * node) 91 void dmres_delete(DMResourceLib *lib, DMResource * node)
105 { 92 {
93 if (lib == NULL)
94 return;
95
106 if (node->prev) 96 if (node->prev)
107 node->prev->next = node->next; 97 node->prev->next = node->next;
108 98
109 if (node->next) 99 if (node->next)
110 node->next->prev = node->prev; 100 node->next->prev = node->prev;
111 else 101 else
112 dfResources->prev = node->prev; 102 lib->resources->prev = node->prev;
113 103
114 node->prev = node->next = NULL; 104 node->prev = node->next = NULL;
115 } 105 }
116 106
117 107
118 DMResource * dmres_find(const char *filename) 108 DMResource * dmres_find(DMResourceLib *lib, const char *filename)
119 { 109 {
120 DMResource *node, *found = NULL; 110 DMResource *node, *found = NULL;
121 111
122 DMRES_LOCK(); 112 if (lib == NULL)
123 113 return NULL;
124 for (node = dfResources; node != NULL; node = node->next) 114
115 dmMutexLock(lib->mutex);
116
117 for (node = lib->resources; node != NULL; node = node->next)
125 { 118 {
126 if (strcmp(node->filename, filename) == 0) 119 if (strcmp(node->filename, filename) == 0)
127 { 120 {
128 found = node; 121 found = node;
129 break; 122 break;
130 } 123 }
131 } 124 }
132 125
133 DMRES_UNLOCK(); 126 dmMutexUnlock(lib->mutex);
134 127
135 return found; 128 return found;
136 } 129 }
137 130
138 131
320 DMPackEntry *node; 313 DMPackEntry *node;
321 int res = DMERR_OK, cres, cdataLeft; 314 int res = DMERR_OK, cres, cdataLeft;
322 z_stream cstream; 315 z_stream cstream;
323 Uint8 * cbuffer = NULL; 316 Uint8 * cbuffer = NULL;
324 317
318 if (handle->lib == NULL || handle->lib->packFile == NULL)
319 return DMERR_NULLPTR;
320
325 // Search PACK nodelist for file 321 // Search PACK nodelist for file
326 if ((node = dm_pack_find(dfResPackFile->entries, handle->filename)) == NULL) 322 if ((node = dm_pack_find(handle->lib->packFile->entries, handle->filename)) == NULL)
327 { 323 {
328 dmError("Entry '%s' not found in PACK file.\n", handle->filename); 324 dmError("Entry '%s' not found in PACK file.\n", handle->filename);
329 res = DMERR_NOT_FOUND; 325 res = DMERR_NOT_FOUND;
330 goto error; 326 goto error;
331 } 327 }
332 328
333 // Seek to entry 329 // Seek to entry
334 if (fseek(dfResPackFile->file, node->offset, SEEK_SET) == -1) 330 if (fseek(handle->lib->packFile->file, node->offset, SEEK_SET) == -1)
335 { 331 {
336 dmError("Could not seek node position in PACK file.\n"); 332 dmError("Could not seek node position in PACK file.\n");
337 res = DMERR_FSEEK; 333 res = DMERR_FSEEK;
338 goto error; 334 goto error;
339 } 335 }
376 cstream.avail_out > 0 && cres == Z_OK) 372 cstream.avail_out > 0 && cres == Z_OK)
377 { 373 {
378 cstream.avail_in = fread( 374 cstream.avail_in = fread(
379 cbuffer, sizeof(Uint8), 375 cbuffer, sizeof(Uint8),
380 (cdataLeft >= DPACK_TMPSIZE) ? DPACK_TMPSIZE : cdataLeft, 376 (cdataLeft >= DPACK_TMPSIZE) ? DPACK_TMPSIZE : cdataLeft,
381 dfResPackFile->file); 377 handle->lib->packFile->file);
382 378
383 cdataLeft -= cstream.avail_in; 379 cdataLeft -= cstream.avail_in;
384 cstream.next_in = cbuffer; 380 cstream.next_in = cbuffer;
385 cres = inflate(&cstream, Z_FULL_FLUSH); 381 cres = inflate(&cstream, Z_FULL_FLUSH);
386 } 382 }
538 { 534 {
539 // Check fops 535 // Check fops
540 if (handle->fops == NULL) 536 if (handle->fops == NULL)
541 { 537 {
542 #ifdef DM_USE_PACKFS 538 #ifdef DM_USE_PACKFS
543 if (dfResFlags & DRF_USE_PACK) 539 if (handle->lib->flags & DRF_USE_PACK)
544 handle->fops = &dfPackFileOps; 540 handle->fops = &dfPackFileOps;
545 #ifdef DM_USE_STDIO 541 #ifdef DM_USE_STDIO
546 else 542 else
547 handle->fops = &dfStdioFileOps; 543 handle->fops = &dfStdioFileOps;
548 #else 544 #else
560 { 556 {
561 int ret = DMERR_INIT_FAIL; 557 int ret = DMERR_INIT_FAIL;
562 558
563 // Check if we want to preload raw data? 559 // Check if we want to preload raw data?
564 if (((handle->flags & DMF_PRELOAD_RAW) || 560 if (((handle->flags & DMF_PRELOAD_RAW) ||
565 (dfResFlags & DRF_PRELOAD_ALL)) && 561 (handle->lib->flags & DRF_PRELOAD_ALL)) &&
566 (handle->flags & DMF_LOADED_RAW) == 0 && 562 (handle->flags & DMF_LOADED_RAW) == 0 &&
567 handle->fops->preload != NULL) 563 handle->fops->preload != NULL)
568 { 564 {
569 ret = handle->fops->preload(handle); 565 ret = handle->fops->preload(handle);
570 if (ret == DMERR_OK) 566 if (ret == DMERR_OK)
586 } 582 }
587 } 583 }
588 } 584 }
589 585
590 // Check if resource data is to be preloaded 586 // Check if resource data is to be preloaded
591 if (((handle->flags & DMF_PRELOAD_RES) || (dfResFlags & DRF_PRELOAD_RES)) && 587 if (((handle->flags & DMF_PRELOAD_RES) || (handle->lib->flags & DRF_PRELOAD_RES)) &&
592 (handle->flags & DMF_LOADED_RES) == 0 && 588 (handle->flags & DMF_LOADED_RES) == 0 &&
593 handle->rops != NULL && 589 handle->rops != NULL &&
594 handle->rops->load != NULL) 590 handle->rops->load != NULL)
595 { 591 {
596 ret = handle->rops->load(handle); 592 ret = handle->rops->load(handle);
607 603
608 return ret; 604 return ret;
609 } 605 }
610 606
611 607
612 DMResource *dmf_open(const char *filename) 608 DMResource *dmf_open(DMResourceLib *lib, const char *filename)
613 { 609 {
614 int ret; 610 int ret;
615 DMResource *handle; 611 DMResource *handle;
616 612
617 // Check master directory for resource 613 // Check master directory for resource
618 if ((handle = dmres_find(filename)) == NULL) 614 if ((handle = dmres_find(lib, filename)) == NULL)
619 { 615 {
620 #ifdef DM_USE_STDIO 616 #ifdef DM_USE_STDIO
621 // Hmm.. does not exist? Fall back to a stdio file 617 // Hmm.. does not exist? Fall back to a stdio file
622 handle = dmres_new(filename, 0, 0); 618 handle = dmres_new(lib, filename, 0, 0);
623 if (handle == NULL) 619 if (handle == NULL)
624 return NULL; 620 return NULL;
625 621
626 handle->fops = &dfStdioFileOps; 622 handle->fops = &dfStdioFileOps;
627 dmres_insert(handle); 623 dmres_insert(lib, handle);
628 #else 624 #else
629 // Stdio not enabled, fail 625 // Stdio not enabled, fail
630 return NULL; 626 return NULL;
631 #endif 627 #endif
632 } 628 }
652 648
653 return NULL; 649 return NULL;
654 } 650 }
655 651
656 652
657 DMResource * dmf_open_memio(const char *filename, Uint8 *buf, size_t len) 653 DMResource * dmf_create_memio(DMResourceLib *lib, const char *filename, Uint8 *buf, size_t len)
658 { 654 {
659 DMResource *handle; 655 DMResource *handle;
660 656
661 // Check master directory for resource 657 // Check master directory for resource
662 if ((handle = dmres_find(filename)) == NULL) 658 if ((handle = dmres_find(lib, filename)) == NULL)
663 { 659 {
664 // Hmm.. does not exist? Fall back to a stdio file 660 // Hmm.. does not exist? Fall back to a stdio file
665 handle = dmres_new(filename, DMF_LOADED_RAW, len); 661 handle = dmres_new(lib, filename, DMF_LOADED_RAW, len);
666 if (handle == NULL) 662 if (handle == NULL)
667 return NULL; 663 return NULL;
668 664
669 handle->fops = &dfMemIOFileOps; 665 handle->fops = &dfMemIOFileOps;
670 handle->data = buf; 666 handle->data = buf;
671 dmres_insert(handle); 667 dmres_insert(lib, handle);
672 } 668 }
673 669
674 // Increase refcount 670 // Increase refcount
675 dmres_ref(handle); 671 dmres_ref(handle);
676 672
679 675
680 676
681 #ifdef DM_USE_STDIO 677 #ifdef DM_USE_STDIO
682 DMResource * dmf_create_stdio(const char *filename, const char *mode) 678 DMResource * dmf_create_stdio(const char *filename, const char *mode)
683 { 679 {
684 DMResource *handle = dmres_new(filename, 0, 0); 680 DMResource *handle = dmres_new(NULL, filename, 0, 0);
685 if (handle == NULL) 681 if (handle == NULL)
686 return NULL; 682 return NULL;
687 683
688 handle->fops = &dfStdioFileOps; 684 handle->fops = &dfStdioFileOps;
689 685
703 } 699 }
704 700
705 701
706 DMResource * dmf_create_stdio_stream(FILE *fh) 702 DMResource * dmf_create_stdio_stream(FILE *fh)
707 { 703 {
708 DMResource *handle = dmres_new("", 0, 0); 704 DMResource *handle = dmres_new(NULL, "", 0, 0);
709 if (handle == NULL) 705 if (handle == NULL)
710 return NULL; 706 return NULL;
711 707
712 handle->fops = &dfStdioFHOps; 708 handle->fops = &dfStdioFHOps;
713 handle->fh = fh; 709 handle->fh = fh;
801 797
802 return (n > 0) ? s : NULL; 798 return (n > 0) ? s : NULL;
803 } 799 }
804 800
805 801
806
807 int dmres_ref(DMResource *node) 802 int dmres_ref(DMResource *node)
808 { 803 {
809 DMRES_LOCK(); 804 if (node->lib != NULL) dmMutexLock(node->lib->mutex);
810 node->atime = time(NULL); 805 node->atime = time(NULL);
811 node->refcount++; 806 node->refcount++;
812 DMRES_UNLOCK(); 807 if (node->lib != NULL) dmMutexUnlock(node->lib->mutex);
813 808
814 return node->refcount; 809 return node->refcount;
815 } 810 }
816 811
817 812
818 int dmres_unref(DMResource *node) 813 int dmres_unref(DMResource *node)
819 { 814 {
820 DMRES_LOCK(); 815 if (node->lib != NULL) dmMutexLock(node->lib->mutex);
821 node->refcount--; 816 node->refcount--;
822 DMRES_UNLOCK(); 817 if (node->lib != NULL) dmMutexUnlock(node->lib->mutex);
823 818
824 return node->refcount; 819 return node->refcount;
825 } 820 }
826 821
827 822
859 } 854 }
860 return flags; 855 return flags;
861 } 856 }
862 857
863 858
864 int dmres_load_resfile(const char *filename) 859 int dmres_load_resfile(DMResourceLib *lib, const char *filename)
865 { 860 {
866 int ret = DMERR_OK; 861 int ret = DMERR_OK;
867 char line[256]; 862 char line[256];
868 FILE *f = fopen(filename, "r"); 863 FILE *f = fopen(filename, "r");
869 if (f == NULL) 864 if (f == NULL)
870 return DMERR_FOPEN; 865 return DMERR_FOPEN;
871 866
872 DMRES_LOCK(); 867 dmMutexLock(lib->mutex);
873 868
874 while (fgets(line, sizeof(line) - 1, f) != NULL) 869 while (fgets(line, sizeof(line) - 1, f) != NULL)
875 { 870 {
876 int fnstart, fsep; 871 int fnstart, fsep;
877 for (fnstart = 0; isspace(line[fnstart]); fnstart++); 872 for (fnstart = 0; isspace(line[fnstart]); fnstart++);
881 int flags, i; 876 int flags, i;
882 for (i = fsep - 1; i > 0 && isspace(line[i]); i--) 877 for (i = fsep - 1; i > 0 && isspace(line[i]); i--)
883 line[i] = 0; 878 line[i] = 0;
884 879
885 for (i = fsep; isspace(line[i]); i++); 880 for (i = fsep; isspace(line[i]); i++);
886
887 if (sscanf(&line[i], "%x", &flags) == 1 &&
888 strlen(&line[fnstart]) > 0)
889 {
890
891 }
892 } 881 }
893 } 882 }
894 883
895 DMRES_UNLOCK(); 884 dmMutexUnlock(lib->mutex);
896 fclose(f); 885 fclose(f);
897 886
898 return ret; 887 return ret;
899 } 888 }
900 889
901 890
902 int dmres_write_resfile(const char *filename) 891 int dmres_write_resfile(DMResourceLib *lib, const char *filename)
903 { 892 {
904 int ret; 893 int ret;
905 DMResource *node; 894 DMResource *node;
906 FILE *f = fopen(filename, "w"); 895 FILE *f = fopen(filename, "w");
907 if (f == NULL) 896 if (f == NULL)
908 return DMERR_FOPEN; 897 return DMERR_FOPEN;
909 898
910 DMRES_LOCK(); 899 dmMutexLock(lib->mutex);
911 900
912 for (node = dfResources; node != NULL; node = node->next) 901 for (node = lib->resources; node != NULL; node = node->next)
913 { 902 {
914 if (fprintf(f, "%s|%08x\n", node->filename, node->flags) < 0) 903 char tmp[64];
904 dmres_flags_to_symbolic(tmp, sizeof(tmp), node->flags);
905 if (fprintf(f, "%s|%s\n", node->filename, tmp) < 0)
915 { 906 {
916 ret = DMERR_FWRITE; 907 ret = DMERR_FWRITE;
917 goto error; 908 goto error;
918 } 909 }
919 } 910 }
920 911
921 error: 912 error:
922 DMRES_UNLOCK(); 913 dmMutexUnlock(lib->mutex);
923 fclose(f); 914 fclose(f);
924 return ret; 915 return ret;
925 } 916 }
926 917
927 918
928 /* Resources subsystem initialization and shutdown routines 919 /* Resources subsystem initialization and shutdown routines
929 */ 920 */
930 int dmres_init(const char *filename, const char *path, const int flags, int (*classifier)(DMResource *)) 921 int dmres_init(DMResourceLib **plib, const char *filename, const char *path, const int flags, int (*classifier)(DMResource *))
931 { 922 {
932 // Check if we are already initialized 923 DMResourceLib *lib;
933 if (dfResInitialized) 924
934 return DMERR_ALREADY_INIT; 925 // Allocate the resource library structure
935 926 if ((*plib = lib = dmMalloc0(sizeof(DMResourceLib))) == NULL)
936 dfResFlags = flags; 927 return DMERR_MALLOC;
937 dfResPath = dm_strdup((path != NULL) ? path : DMRES_DATA_PATH); 928
938 dfResourcesMutex = dmCreateMutex(); 929 // Basic data
930 lib->mutex = dmCreateMutex();
931 lib->flags = flags;
932 lib->resPath = dm_strdup((path != NULL) ? path : DMRES_DATA_PATH);
939 933
940 934
941 if (flags & DRF_USE_PACK) 935 if (flags & DRF_USE_PACK)
942 { 936 {
943 #ifdef DM_USE_PACKFS 937 #ifdef DM_USE_PACKFS
944 int ret; 938 int ret;
945 DMPackEntry *node; 939 DMPackEntry *node;
946 940
947 dfResPackFilename = dm_strdup((filename != NULL) ? filename : DMRES_DATA_PACK); 941 lib->packFilename = dm_strdup((filename != NULL) ? filename : DMRES_DATA_PACK);
948 942
949 // Initialize PACK, open as read-only 943 // Initialize PACK, open as read-only
950 ret = dm_pack_open(dfResPackFilename, &dfResPackFile, TRUE); 944 ret = dm_pack_open(lib->packFilename, &lib->packFile, TRUE);
951 if (ret != DMERR_OK) 945 if (ret != DMERR_OK)
952 { 946 {
953 dmError("Error opening PACK file '%s', #%i: %s\n", 947 dmError("Error opening PACK file '%s', #%i: %s\n",
954 dfResPackFilename, ret, dmErrorStr(ret)); 948 lib->packFilename, ret, dmErrorStr(ret));
955 949
956 return DMERR_INIT_FAIL; 950 return DMERR_INIT_FAIL;
957 } 951 }
958 952
959 // Initialize resources from a PACK file 953 // Initialize resources from a PACK file
960 for (node = dfResPackFile->entries; node != NULL; node = node->next) 954 for (node = lib->packFile->entries; node != NULL; node = node->next)
961 { 955 {
962 DMResource *res = dmres_new(node->filename, node->resFlags & DMF_MASK, node->size); 956 DMResource *res = dmres_new(lib, node->filename, node->resFlags & DMF_MASK, node->size);
963 if (res == NULL) 957 if (res == NULL)
964 { 958 {
965 dmError("Could not allocate memory for resource node '%s' [0x%08x], %d.\n", 959 dmError("Could not allocate memory for resource node '%s' [0x%08x], %d.\n",
966 node->filename, node->resFlags, node->size); 960 node->filename, node->resFlags, node->size);
967 return DMERR_INIT_FAIL; 961 return DMERR_INIT_FAIL;
968 } 962 }
969 963
970 dmres_insert(res); 964 dmres_insert(lib, res);
971 } 965 }
972 966
973 #else 967 #else
974 // PACK not compiled in, FAIL! 968 // PACK not compiled in, FAIL!
975 return DMERR_INIT_FAIL; 969 return DMERR_INIT_FAIL;
976 #endif 970 #endif
977 } 971 }
978 else 972 else
979 { 973 {
980 // Initialize resources from a resource directory 974 // Initialize resources from a resource directory
981 char *resFilename = dm_strdup_printf("%s%s", dfResPath, DMRES_RES_FILE); 975 char *resFilename = dm_strdup_printf("%s%s", lib->resPath, DMRES_RES_FILE);
982 int ret = dmres_load_resfile(resFilename); 976 int ret = dmres_load_resfile(lib, resFilename);
983 dmFree(resFilename); 977 dmFree(resFilename);
984 978
985 if (ret != DMERR_OK) 979 if (ret != DMERR_OK)
986 return DMERR_INIT_FAIL; 980 return DMERR_INIT_FAIL;
987 } 981 }
988 982
989 // Okay, classify resources 983 // Okay, classify resources
990 if (dfResources != NULL && classifier != NULL) 984 if (lib->resources != NULL && classifier != NULL)
991 { 985 {
992 DMResource *node; 986 DMResource *node;
993 for (node = dfResources; node != NULL; node = node->next) 987 for (node = lib->resources; node != NULL; node = node->next)
994 { 988 {
995 int ret = classifier(node); 989 int ret = classifier(node);
996 if (ret != DMERR_OK) 990 if (ret != DMERR_OK)
997 return ret; 991 return ret;
998 } 992 }
999 } 993 }
1000 994
1001 // Initialization complete 995 // Initialization complete
1002 dfResInitialized = TRUE;
1003 return DMERR_OK; 996 return DMERR_OK;
1004 } 997 }
1005 998
1006 999
1007 void dmres_close(void) 1000 int dmres_close(DMResourceLib *lib)
1008 { 1001 {
1009 DMResource *node; 1002 DMResource *node;
1010 DMRES_LOCK(); 1003
1011 1004 if (lib == NULL)
1012 if (!dfResInitialized) 1005 return DMERR_NULLPTR;
1013 return; 1006
1014 1007 dmMutexLock(lib->mutex);
1008
1015 // Shutdown possible subsystems 1009 // Shutdown possible subsystems
1016 #ifdef DM_USE_PACKFS 1010 #ifdef DM_USE_PACKFS
1017 if (dfResFlags & DRF_USE_PACK) 1011 if (lib->flags & DRF_USE_PACK)
1018 { 1012 {
1019 int res = dm_pack_close(dfResPackFile); 1013 int res = dm_pack_close(lib->packFile);
1020 if (res != DMERR_OK) 1014 if (res != DMERR_OK)
1021 { 1015 {
1022 dmError("Error closing PACK, #%i: %s\n", 1016 dmError("Error closing PACK, #%i: %s\n",
1023 res, dmErrorStr(res)); 1017 res, dmErrorStr(res));
1024 } 1018 }
1025 1019
1026 dmFree(dfResPackFilename); 1020 dmFree(lib->packFilename);
1027 } 1021 }
1028 #endif 1022 #endif
1029 1023
1030 // Free resource entries 1024 // Free resource entries
1031 node = dfResources; 1025 node = lib->resources;
1032 while (node != NULL) 1026 while (node != NULL)
1033 { 1027 {
1034 DMResource *next = node->next; 1028 DMResource *next = node->next;
1035 dmres_free(node); 1029 dmres_free(node);
1036 node = next; 1030 node = next;
1037 } 1031 }
1038 1032
1039 // Etc. 1033 // Etc.
1040 dmFree(dfResPath); 1034 dmFree(lib->resPath);
1041 DMRES_UNLOCK(); 1035 dmMutexUnlock(lib->mutex);
1042 dmDestroyMutex(dfResourcesMutex); 1036 dmDestroyMutex(lib->mutex);
1043 dfResInitialized = FALSE; 1037 return DMERR_OK;
1044 } 1038 }
1045 1039
1046 1040
1047 int dmres_preload(BOOL start, int *loaded, int *total) 1041 int dmres_preload(DMResourceLib *lib, BOOL start, int *loaded, int *total)
1048 { 1042 {
1049 static DMResource *dfPreload = NULL;
1050 int ret = DMERR_OK; 1043 int ret = DMERR_OK;
1051 1044
1052 DMRES_LOCK(); 1045 dmMutexLock(lib->mutex);
1053 1046
1054 // Initialize preloading 1047 // Initialize preloading
1055 if (dfPreload == NULL || start) 1048 if (lib->preload == NULL || start)
1056 { 1049 {
1057 DMResource *node; 1050 DMResource *node;
1058 1051
1059 dfPreload = dfResources; 1052 lib->preload = lib->resources;
1060 *loaded = 0; 1053 *loaded = 0;
1061 *total = 0; 1054 *total = 0;
1062 1055
1063 // Calculate total number of resources to be preloaded 1056 // Calculate total number of resources to be preloaded
1064 for (node = dfResources; node != NULL; node = node->next) 1057 for (node = lib->resources; node != NULL; node = node->next)
1065 { 1058 {
1066 if ((dfResFlags & (DRF_PRELOAD_ALL | DRF_PRELOAD_RES)) || 1059 if ((lib->flags & (DRF_PRELOAD_ALL | DRF_PRELOAD_RES)) ||
1067 (node->flags & (DMF_PRELOAD_RAW | DMF_PRELOAD_RES))) 1060 (node->flags & (DMF_PRELOAD_RAW | DMF_PRELOAD_RES)))
1068 (*total)++; 1061 (*total)++;
1069 } 1062 }
1070 } 1063 }
1071 else 1064 else
1072 if (dfPreload != NULL) 1065 if (lib->preload != NULL)
1073 { 1066 {
1074 // Initialize fops and preload 1067 // Initialize fops and preload
1075 dmf_init_fops(dfPreload); 1068 dmf_init_fops(lib->preload);
1076 if ((ret = dmf_preload(dfPreload)) != DMERR_OK) 1069 if ((ret = dmf_preload(lib->preload)) != DMERR_OK)
1077 goto error; 1070 goto error;
1078 1071
1079 (*loaded)++; 1072 (*loaded)++;
1080 dfPreload = dfPreload->next; 1073 lib->preload = lib->preload->next;
1081 } 1074 }
1082 1075
1083 DMRES_UNLOCK(); 1076 dmMutexUnlock(lib->mutex);
1084 return (dfPreload == NULL) ? DMERR_OK : DMERR_PROGRESS; 1077 return (lib->preload == NULL) ? DMERR_OK : DMERR_PROGRESS;
1085 1078
1086 error: 1079 error:
1087 DMRES_UNLOCK(); 1080 dmMutexUnlock(lib->mutex);
1088 return ret; 1081 return ret;
1089 } 1082 }
1090 1083
1091 1084
1092 void dmres_prune(int agems, int flags) 1085 void dmres_prune(DMResourceLib *lib, int agems, int flags)
1093 { 1086 {
1094 DMResource *node; 1087 DMResource *node;
1095 int currtime = time(NULL); 1088 int currtime = time(NULL);
1096 DMRES_LOCK(); 1089 dmMutexLock(lib->mutex);
1097 1090
1098 for (node = dfResources; node != NULL; node = node->next) 1091 for (node = lib->resources; node != NULL; node = node->next)
1099 { 1092 {
1100 // Check if node has refcount of 0 and is 1093 // Check if node has refcount of 0 and is
1101 // not marked as persistent resource 1094 // not marked as persistent resource
1102 if (node->refcount == 0 && 1095 if (node->refcount == 0 &&
1103 (node->flags & DMF_PERSIST) == 0 && 1096 (node->flags & DMF_PERSIST) == 0 &&
1113 dmres_free_raw_data(node); 1106 dmres_free_raw_data(node);
1114 } 1107 }
1115 } 1108 }
1116 } 1109 }
1117 1110
1118 DMRES_UNLOCK(); 1111 dmMutexUnlock(lib->mutex);
1119 } 1112 }
1120 1113
1121 1114
1122 /* Helper resource access routines 1115 /* Helper resource access routines
1123 */ 1116 */