📄 prlayer.c
字号:
static PRStatus PR_CALLBACK pl_DefGetpeername (PRFileDesc *fd, PRNetAddr *addr){ PR_ASSERT(fd != NULL); PR_ASSERT(fd->lower != NULL); return (fd->lower->methods->getpeername)(fd->lower, addr);}static PRStatus PR_CALLBACK pl_DefGetsocketoption ( PRFileDesc *fd, PRSocketOptionData *data){ PR_ASSERT(fd != NULL); PR_ASSERT(fd->lower != NULL); return (fd->lower->methods->getsocketoption)(fd->lower, data);}static PRStatus PR_CALLBACK pl_DefSetsocketoption ( PRFileDesc *fd, const PRSocketOptionData *data){ PR_ASSERT(fd != NULL); PR_ASSERT(fd->lower != NULL); return (fd->lower->methods->setsocketoption)(fd->lower, data);}static PRInt32 PR_CALLBACK pl_DefSendfile ( PRFileDesc *sd, PRSendFileData *sfd, PRTransmitFileFlags flags, PRIntervalTime timeout){ PR_ASSERT(sd != NULL); PR_ASSERT(sd->lower != NULL); return sd->lower->methods->sendfile( sd->lower, sfd, flags, timeout);}/* Methods for the top of the stack. Just call down to the next fd. */static PRIOMethods pl_methods = { PR_DESC_LAYERED, pl_TopClose, pl_DefRead, pl_DefWrite, pl_DefAvailable, pl_DefAvailable64, pl_DefFsync, pl_DefSeek, pl_DefSeek64, pl_DefFileInfo, pl_DefFileInfo64, pl_DefWritev, pl_DefConnect, pl_TopAccept, pl_DefBind, pl_DefListen, pl_DefShutdown, pl_DefRecv, pl_DefSend, pl_DefRecvfrom, pl_DefSendto, pl_DefPoll, pl_DefAcceptread, pl_DefTransmitfile, pl_DefGetsockname, pl_DefGetpeername, (PRReservedFN)_PR_InvalidInt, (PRReservedFN)_PR_InvalidInt, pl_DefGetsocketoption, pl_DefSetsocketoption, pl_DefSendfile, pl_DefConnectcontinue, (PRReservedFN)_PR_InvalidInt, (PRReservedFN)_PR_InvalidInt, (PRReservedFN)_PR_InvalidInt, (PRReservedFN)_PR_InvalidInt};PR_IMPLEMENT(const PRIOMethods*) PR_GetDefaultIOMethods(void){ return &pl_methods;} /* PR_GetDefaultIOMethods */PR_IMPLEMENT(PRFileDesc*) PR_CreateIOLayerStub( PRDescIdentity ident, const PRIOMethods *methods){ PRFileDesc *fd = NULL; PR_ASSERT((PR_NSPR_IO_LAYER != ident) && (PR_TOP_IO_LAYER != ident)); if ((PR_NSPR_IO_LAYER == ident) || (PR_TOP_IO_LAYER == ident)) PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); else { fd = PR_NEWZAP(PRFileDesc); if (NULL == fd) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); else { fd->methods = methods; fd->dtor = pl_FDDestructor; fd->identity = ident; } } return fd;} /* PR_CreateIOLayerStub *//* * PR_CreateIOLayer * Create a new style stack, where the stack top is a dummy header. * Unlike the old style stacks, the contents of the stack head * are not modified when a layer is pushed onto or popped from a new * style stack. */PR_IMPLEMENT(PRFileDesc*) PR_CreateIOLayer(PRFileDesc *top){ PRFileDesc *fd = NULL; fd = PR_NEWZAP(PRFileDesc); if (NULL == fd) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); else { fd->methods = &pl_methods; fd->dtor = pl_FDDestructor; fd->identity = PR_IO_LAYER_HEAD; fd->higher = NULL; fd->lower = top; top->higher = fd; top->lower = NULL; } return fd;} /* PR_CreateIOLayer *//* * _PR_DestroyIOLayer * Delete the stack head of a new style stack. */static PRStatus _PR_DestroyIOLayer(PRFileDesc *stack){ if (NULL == stack) return PR_FAILURE; else { PR_DELETE(stack); return PR_SUCCESS; }} /* _PR_DestroyIOLayer */PR_IMPLEMENT(PRStatus) PR_PushIOLayer( PRFileDesc *stack, PRDescIdentity id, PRFileDesc *fd){ PRFileDesc *insert = PR_GetIdentitiesLayer(stack, id); PR_ASSERT(fd != NULL); PR_ASSERT(stack != NULL); PR_ASSERT(insert != NULL); PR_ASSERT(PR_IO_LAYER_HEAD != id); if ((NULL == stack) || (NULL == fd) || (NULL == insert)) { PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); return PR_FAILURE; } if (stack == insert) { /* going on top of the stack */ /* old-style stack */ PRFileDesc copy = *stack; *stack = *fd; *fd = copy; fd->higher = stack; stack->lower = fd; stack->higher = NULL; } else { /* * going somewhere in the middle of the stack for both old and new * style stacks, or going on top of stack for new style stack */ fd->lower = insert; fd->higher = insert->higher; insert->higher->lower = fd; insert->higher = fd; } return PR_SUCCESS;}PR_IMPLEMENT(PRFileDesc*) PR_PopIOLayer(PRFileDesc *stack, PRDescIdentity id){ PRFileDesc *extract = PR_GetIdentitiesLayer(stack, id); PR_ASSERT(0 != id); PR_ASSERT(NULL != stack); PR_ASSERT(NULL != extract); if ((NULL == stack) || (0 == id) || (NULL == extract)) { PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); return NULL; } if (extract == stack) { /* popping top layer of the stack */ /* old style stack */ PRFileDesc copy = *stack; extract = stack->lower; *stack = *extract; *extract = copy; stack->higher = NULL; } else if ((PR_IO_LAYER_HEAD == stack->identity) && (extract == stack->lower) && (extract->lower == NULL)) { /* * new style stack * popping the only layer in the stack; delete the stack too */ stack->lower = NULL; _PR_DestroyIOLayer(stack); } else { /* for both kinds of stacks */ extract->lower->higher = extract->higher; extract->higher->lower = extract->lower; } extract->higher = extract->lower = NULL; return extract;} /* PR_PopIOLayer */#define ID_CACHE_INCREMENT 16typedef struct _PRIdentity_cache{ PRLock *ml; char **name; PRIntn length; PRDescIdentity ident;} _PRIdentity_cache;static _PRIdentity_cache identity_cache;PR_IMPLEMENT(PRDescIdentity) PR_GetUniqueIdentity(const char *layer_name){ PRDescIdentity identity, length; char **names = NULL, *name = NULL, **old = NULL; if (!_pr_initialized) _PR_ImplicitInitialization(); PR_ASSERT((PRDescIdentity)0x7fff > identity_cache.ident); if (NULL != layer_name) { name = (char*)PR_Malloc(strlen(layer_name) + 1); if (NULL == name) { PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); return PR_INVALID_IO_LAYER; } strcpy(name, layer_name); } /* this initial code runs unsafe */retry: PR_ASSERT(NULL == names); length = identity_cache.length; if (length < (identity_cache.ident + 1)) { length += ID_CACHE_INCREMENT; names = (char**)PR_CALLOC(length * sizeof(char*)); if (NULL == names) { if (NULL != name) PR_DELETE(name); PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); return PR_INVALID_IO_LAYER; } } /* now we get serious about thread safety */ PR_Lock(identity_cache.ml); PR_ASSERT(identity_cache.ident <= identity_cache.length); identity = identity_cache.ident + 1; if (identity > identity_cache.length) /* there's no room */ { /* we have to do something - hopefully it's already done */ if ((NULL != names) && (length >= identity)) { /* what we did is still okay */ memcpy( names, identity_cache.name, identity_cache.length * sizeof(char*)); old = identity_cache.name; identity_cache.name = names; identity_cache.length = length; names = NULL; } else { PR_ASSERT(identity_cache.ident <= identity_cache.length); PR_Unlock(identity_cache.ml); if (NULL != names) PR_DELETE(names); goto retry; } } if (NULL != name) /* there's a name to be stored */ { identity_cache.name[identity] = name; } identity_cache.ident = identity; PR_ASSERT(identity_cache.ident <= identity_cache.length); PR_Unlock(identity_cache.ml); if (NULL != old) PR_DELETE(old); if (NULL != names) PR_DELETE(names); return identity;} /* PR_GetUniqueIdentity */PR_IMPLEMENT(const char*) PR_GetNameForIdentity(PRDescIdentity ident){ if (!_pr_initialized) _PR_ImplicitInitialization(); if (PR_TOP_IO_LAYER == ident) return NULL; PR_ASSERT(ident <= identity_cache.ident); return (ident > identity_cache.ident) ? NULL : identity_cache.name[ident];} /* PR_GetNameForIdentity */PR_IMPLEMENT(PRDescIdentity) PR_GetLayersIdentity(PRFileDesc* fd){ PR_ASSERT(NULL != fd); if (PR_IO_LAYER_HEAD == fd->identity) { PR_ASSERT(NULL != fd->lower); return fd->lower->identity; } else return fd->identity;} /* PR_GetLayersIdentity */PR_IMPLEMENT(PRFileDesc*) PR_GetIdentitiesLayer(PRFileDesc* fd, PRDescIdentity id){ PRFileDesc *layer = fd; if (PR_TOP_IO_LAYER == id) { if (PR_IO_LAYER_HEAD == fd->identity) return fd->lower; else return fd; } for (layer = fd; layer != NULL; layer = layer->lower) { if (id == layer->identity) return layer; } for (layer = fd; layer != NULL; layer = layer->higher) { if (id == layer->identity) return layer; } return NULL;} /* PR_GetIdentitiesLayer */void _PR_InitLayerCache(void){ memset(&identity_cache, 0, sizeof(identity_cache)); identity_cache.ml = PR_NewLock(); PR_ASSERT(NULL != identity_cache.ml);} /* _PR_InitLayerCache */void _PR_CleanupLayerCache(void){ if (identity_cache.ml) { PR_DestroyLock(identity_cache.ml); identity_cache.ml = NULL; } if (identity_cache.name) { PRDescIdentity ident; for (ident = 0; ident <= identity_cache.ident; ident++) PR_DELETE(identity_cache.name[ident]); PR_DELETE(identity_cache.name); }} /* _PR_CleanupLayerCache *//* prlayer.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -