|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include <stdlib.h> ! 3: #include <string.h> ! 4: ! 5: #ifdef __unix__ ! 6: #define XP_UNIX ! 7: #else ! 8: #define XP_PC ! 9: #define XP_WIN ! 10: #endif ! 11: ! 12: #define JS_THREADSAFE ! 13: #include <jsapi.h> ! 14: #include "threadwrap.h" ! 15: #include "js_request.h" ! 16: ! 17: #ifdef DEBUG_JS_REQUESTS ! 18: ! 19: #define DEBUG ! 20: #include <jscntxt.h> ! 21: ! 22: enum last_request_type { ! 23: LAST_REQUEST_TYPE_NONE ! 24: ,LAST_REQUEST_TYPE_BEGIN ! 25: ,LAST_REQUEST_TYPE_END ! 26: ,LAST_REQUEST_TYPE_SUSPEND ! 27: ,LAST_REQUEST_TYPE_RESUME ! 28: }; ! 29: static const char *type_names[5]={"None", "BeginRequest", "EndRequest", "SuspendRequest", "ResumeRequest"}; ! 30: ! 31: struct request_log { ! 32: JSContext* cx; ! 33: enum last_request_type type; ! 34: const char* file; ! 35: unsigned long line; ! 36: struct request_log* next; ! 37: struct request_log* prev; ! 38: }; ! 39: ! 40: static struct request_log* first_request; ! 41: static int initialized=0; ! 42: static pthread_mutex_t req_mutex; ! 43: static char str[1024]; ! 44: ! 45: static void logstr(void) ! 46: { ! 47: FILE *f; ! 48: ! 49: if((f=fopen("../data/logs/JS_RequestErrors.log", "a"))!=NULL) { ! 50: fputs(str, f); ! 51: fclose(f); ! 52: } ! 53: else { ! 54: fputs(str, stderr); ! 55: } ! 56: } ! 57: ! 58: static struct request_log *match_request(JSContext *cx) ! 59: { ! 60: struct request_log *ent; ! 61: ! 62: for(ent=first_request; ent != NULL; ent=ent->next) { ! 63: if(ent->cx==cx) ! 64: return(ent); ! 65: } ! 66: ! 67: ent=malloc(sizeof(struct request_log)); ! 68: if(ent != NULL) { ! 69: memset(ent, 0, sizeof(struct request_log)); ! 70: ent->cx=cx; ! 71: ent->type=LAST_REQUEST_TYPE_NONE; ! 72: ent->prev=NULL; ! 73: ent->next=first_request; ! 74: if(first_request != NULL) { ! 75: first_request->prev=ent; ! 76: } ! 77: first_request=ent; ! 78: return(ent); ! 79: } ! 80: return(NULL); ! 81: } ! 82: ! 83: static void initialize_request(void) ! 84: { ! 85: pthread_mutex_init(&req_mutex, NULL); ! 86: initialized=1; ! 87: } ! 88: ! 89: void js_debug_beginrequest(JSContext *cx, const char *file, unsigned long line) ! 90: { ! 91: struct request_log *req; ! 92: ! 93: if(!initialized) ! 94: initialize_request(); ! 95: pthread_mutex_lock(&req_mutex); ! 96: req=match_request(cx); ! 97: if(req==NULL) { ! 98: strcpy(str,"Missing req in Begin\n"); ! 99: logstr(); ! 100: return; ! 101: } ! 102: switch(req->type) { ! 103: case LAST_REQUEST_TYPE_NONE: ! 104: case LAST_REQUEST_TYPE_END: ! 105: break; ! 106: case LAST_REQUEST_TYPE_BEGIN: ! 107: case LAST_REQUEST_TYPE_SUSPEND: ! 108: case LAST_REQUEST_TYPE_RESUME: ! 109: sprintf(str,"Begin after %s from %s:%u at %s:%u (%p)\n",type_names[req->type],req->file,req->line,file,line,req->cx); ! 110: logstr(); ! 111: break; ! 112: } ! 113: switch(cx->requestDepth) { ! 114: case 0: ! 115: break; ! 116: case 1: ! 117: default: ! 118: sprintf(str,"depth=%u at Begin after %s from %s:%u at %s:%u (%p)\n",cx->requestDepth,type_names[req->type],req->file,req->line,file,line,req->cx); ! 119: logstr(); ! 120: break; ! 121: } ! 122: ! 123: req->type=LAST_REQUEST_TYPE_BEGIN; ! 124: req->file=file; ! 125: req->line=line; ! 126: JS_BeginRequest(cx); ! 127: pthread_mutex_unlock(&req_mutex); ! 128: } ! 129: ! 130: void js_debug_endrequest(JSContext *cx, const char *file, unsigned long line) ! 131: { ! 132: struct request_log *req; ! 133: ! 134: if(!initialized) ! 135: initialize_request(); ! 136: pthread_mutex_lock(&req_mutex); ! 137: req=match_request(cx); ! 138: if(req==NULL) { ! 139: strcpy(str,"Missing req in End\n"); ! 140: logstr(); ! 141: return; ! 142: } ! 143: switch(req->type) { ! 144: case LAST_REQUEST_TYPE_BEGIN: ! 145: if(req->file) { ! 146: if(strcmp(req->file, file) != 0 || line < req->line) { ! 147: sprintf(str,"Suspicious End after %s from %s:%u at %s:%u (%p)\n",type_names[req->type],req->file,req->line,file,line,req->cx); ! 148: } ! 149: break; ! 150: } ! 151: case LAST_REQUEST_TYPE_RESUME: ! 152: break; ! 153: case LAST_REQUEST_TYPE_NONE: ! 154: case LAST_REQUEST_TYPE_END: ! 155: case LAST_REQUEST_TYPE_SUSPEND: ! 156: sprintf(str,"End after %s from %s:%u at %s:%u (%p)\n",type_names[req->type],req->file,req->line,file,line,req->cx); ! 157: logstr(); ! 158: break; ! 159: } ! 160: switch(cx->requestDepth) { ! 161: case 0: ! 162: default: ! 163: sprintf(str,"depth=%u at End after %s from %s:%u at %s:%u (%p)\n",cx->requestDepth,type_names[req->type],req->file,req->line,file,line,req->cx); ! 164: logstr(); ! 165: break; ! 166: case 1: ! 167: break; ! 168: } ! 169: ! 170: req->type=LAST_REQUEST_TYPE_END; ! 171: req->file=file; ! 172: req->line=line; ! 173: JS_EndRequest(cx); ! 174: if(cx->requestDepth==0) { ! 175: if(req->prev != NULL) ! 176: req->prev->next=req->next; ! 177: if(req->next != NULL) ! 178: req->next->prev=req->prev; ! 179: if(first_request==req) { ! 180: if(req->prev != NULL) ! 181: first_request=req->prev; ! 182: else ! 183: first_request=req->next; ! 184: } ! 185: free(req); ! 186: } ! 187: pthread_mutex_unlock(&req_mutex); ! 188: } ! 189: ! 190: jsrefcount js_debug_suspendrequest(JSContext *cx, const char *file, unsigned long line) ! 191: { ! 192: struct request_log *req; ! 193: jsrefcount ret; ! 194: ! 195: if(!initialized) ! 196: initialize_request(); ! 197: pthread_mutex_lock(&req_mutex); ! 198: req=match_request(cx); ! 199: if(req==NULL) { ! 200: strcpy(str,"Missing req in Suspend\n"); ! 201: logstr(); ! 202: return -1; ! 203: } ! 204: switch(req->type) { ! 205: case LAST_REQUEST_TYPE_BEGIN: ! 206: case LAST_REQUEST_TYPE_RESUME: ! 207: break; ! 208: case LAST_REQUEST_TYPE_NONE: ! 209: if(req->file==NULL) /* Assumed to be a provided request */ ! 210: break; ! 211: case LAST_REQUEST_TYPE_END: ! 212: case LAST_REQUEST_TYPE_SUSPEND: ! 213: sprintf(str,"Suspend after %s from %s:%u at %s:%u (%p)\n",type_names[req->type],req->file,req->line,file,line,req->cx); ! 214: logstr(); ! 215: break; ! 216: } ! 217: switch(cx->requestDepth) { ! 218: case 0: ! 219: default: ! 220: sprintf(str,"depth=%u at Suspend after %s from %s:%u at %s:%u (%p)\n",cx->requestDepth,type_names[req->type],req->file,req->line,file,line,req->cx); ! 221: logstr(); ! 222: break; ! 223: case 1: ! 224: break; ! 225: } ! 226: ! 227: req->type=LAST_REQUEST_TYPE_SUSPEND; ! 228: req->file=file; ! 229: req->line=line; ! 230: ret=JS_SuspendRequest(cx); ! 231: pthread_mutex_unlock(&req_mutex); ! 232: return(ret); ! 233: } ! 234: ! 235: void js_debug_resumerequest(JSContext *cx, jsrefcount rc, const char *file, unsigned long line) ! 236: { ! 237: struct request_log *req; ! 238: ! 239: if(!initialized) ! 240: initialize_request(); ! 241: pthread_mutex_lock(&req_mutex); ! 242: req=match_request(cx); ! 243: if(req==NULL) { ! 244: strcpy(str,"Missing req in Resume\n"); ! 245: logstr(); ! 246: return; ! 247: } ! 248: switch(req->type) { ! 249: case LAST_REQUEST_TYPE_SUSPEND: ! 250: break; ! 251: case LAST_REQUEST_TYPE_NONE: ! 252: case LAST_REQUEST_TYPE_END: ! 253: case LAST_REQUEST_TYPE_BEGIN: ! 254: case LAST_REQUEST_TYPE_RESUME: ! 255: sprintf(str,"Resume after %s from %s:%u at %s:%u (%p)\n",type_names[req->type],req->file,req->line,file,line,req->cx); ! 256: logstr(); ! 257: break; ! 258: } ! 259: switch(cx->requestDepth) { ! 260: case 1: ! 261: default: ! 262: sprintf(str,"depth=%u at Suspend after %s from %s:%u at %s:%u (%p)\n",cx->requestDepth,type_names[req->type],req->file,req->line,file,line,req->cx); ! 263: logstr(); ! 264: break; ! 265: case 0: ! 266: break; ! 267: } ! 268: ! 269: req->type=LAST_REQUEST_TYPE_RESUME; ! 270: req->file=file; ! 271: req->line=line; ! 272: JS_ResumeRequest(cx, rc); ! 273: pthread_mutex_unlock(&req_mutex); ! 274: } ! 275: ! 276: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.