static struct hostent *my_gethostbyaddr_r(const char *addr, int length, int type, struct hostent *hostp, char *buffer, int buflen, int *h_errnop) { struct hostent dest; struct hostent *src; struct hostent *rval = NULL; /* FIXME this should have been done in 'erl'_init()? */ if (!ei_resolve_initialized) ei_init_resolve(); #ifdef _REENTRANT /* === BEGIN critical section === */ if (ei_mutex_lock(ei_gethost_sem,0) != 0) { *h_errnop = NO_RECOVERY; return NULL; } #endif /* _REENTRANT */ /* lookup the data */ if ((src = ei_gethostbyaddr(addr,length,type))) { /* copy to caller's buffer */ if (!copy_hostent(&dest,src,buffer,buflen)) { /* success */ *hostp = dest; *h_errnop = 0; rval = hostp; } else { /* failure - buffer size */ #ifdef __WIN32__ SetLastError(ERROR_INSUFFICIENT_BUFFER); #else errno = ERANGE; #endif *h_errnop = 0; } } else { /* failure - lookup */ #ifdef __WIN32__ *h_errnop = WSAGetLastError(); #else *h_errnop = h_errno; #endif } #ifdef _REENTRANT /* === END critical section === */ ei_mutex_unlock(ei_gethost_sem); #endif /* _REENTRANT */ return rval; }
/* get an eterm, from the freelist if possible or from malloc() */ void *erl_eterm_alloc (void) { #ifdef PURIFY ETERM *p; if ((p = malloc(sizeof(*p)))) { memset(p, WIPE_CHAR, sizeof(*p)); } return p; #else struct fix_block *b; #ifdef _REENTRANT ei_mutex_lock(erl_eterm_state->lock, 0); #endif /* _REENTRANT */ /* try to pop block from head of freelist */ if ((b = erl_eterm_state->freelist) != NULL) { erl_eterm_state->freelist = b->next; erl_eterm_state->freed--; } else if ((b = malloc(sizeof(*b))) == NULL) { erl_errno = ENOMEM; } erl_eterm_state->allocated++; b->free = 0; b->next = NULL; #ifdef _REENTRANT ei_mutex_unlock(erl_eterm_state->lock); #endif /* _REENTRANT */ return (void *) &b->term; #endif /* !PURIFY */ }
/* free an eterm back to the freelist */ void erl_eterm_free(void *p) { #ifdef PURIFY if (p) { memset(p, WIPE_CHAR, sizeof(ETERM)); } free(p); #else struct fix_block *b = p; if (b) { if (b->free) { #ifdef DEBUG fprintf(stderr,"erl_eterm_free: attempt to free already freed block %p\n",b); #endif return; } #ifdef _REENTRANT ei_mutex_lock(erl_eterm_state->lock,0); #endif /* _REENTRANT */ b->free = 1; b->next = erl_eterm_state->freelist; erl_eterm_state->freelist = b; erl_eterm_state->freed++; erl_eterm_state->allocated--; #ifdef _REENTRANT ei_mutex_unlock(erl_eterm_state->lock); #endif /* _REENTRANT */ } #endif /* !PURIFY */ }
static int put_ei_socket_info(int fd, int dist_version, char* cookie, ei_cnode *ec) { int i; #ifdef _REENTRANT ei_mutex_lock(ei_sockets_lock, 0); #endif /* _REENTRANT */ for (i = 0; i < ei_n_sockets; ++i) { if (ei_sockets[i].socket == fd) { if (dist_version == -1) { memmove(&ei_sockets[i], &ei_sockets[i+1], sizeof(ei_sockets[0])*(ei_n_sockets-i-1)); } else { ei_sockets[i].dist_version = dist_version; /* Copy the content, see ei_socket_info */ ei_sockets[i].cnode = *ec; strcpy(ei_sockets[i].cookie, cookie); } #ifdef _REENTRANT ei_mutex_unlock(ei_sockets_lock); #endif /* _REENTRANT */ return 0; } } if (ei_n_sockets == ei_sz_sockets) { ei_sz_sockets += 5; ei_sockets = realloc(ei_sockets, sizeof(ei_sockets[0])*ei_sz_sockets); if (ei_sockets == NULL) { ei_sz_sockets = ei_n_sockets = 0; #ifdef _REENTRANT ei_mutex_unlock(ei_sockets_lock); #endif /* _REENTRANT */ return -1; } ei_sockets[ei_n_sockets].socket = fd; ei_sockets[ei_n_sockets].dist_version = dist_version; ei_sockets[i].cnode = *ec; strcpy(ei_sockets[ei_n_sockets].cookie, cookie); ++ei_n_sockets; } #ifdef _REENTRANT ei_mutex_unlock(ei_sockets_lock); #endif /* _REENTRANT */ return 0; }
static ei_socket_info* get_ei_socket_info(int fd) { int i; #ifdef _REENTRANT ei_mutex_lock(ei_sockets_lock, 0); #endif /* _REENTRANT */ for (i = 0; i < ei_n_sockets; ++i) if (ei_sockets[i].socket == fd) { /*fprintf("get_ei_socket_info %d %d \"%s\"\n", fd, ei_sockets[i].dist_version, ei_sockets[i].cookie);*/ #ifdef _REENTRANT ei_mutex_unlock(ei_sockets_lock); #endif /* _REENTRANT */ return &ei_sockets[i]; } #ifdef _REENTRANT ei_mutex_unlock(ei_sockets_lock); #endif /* _REENTRANT */ return NULL; }
/* really free the freelist */ void erl_eterm_release (void) { #if !defined(PURIFY) struct fix_block *b; #ifdef _REENTRANT ei_mutex_lock(erl_eterm_state->lock,0); #endif /* _REENTRANT */ { while (erl_eterm_state->freelist != NULL) { b = erl_eterm_state->freelist; erl_eterm_state->freelist = b->next; free(b); erl_eterm_state->freed--; } } #ifdef _REENTRANT ei_mutex_unlock(erl_eterm_state->lock); #endif /* _REENTRANT */ #endif /* !PURIFY */ }