int rpmrubyRunThread(rpmruby ruby) { int ec = 0; #if defined(HAVE_RUBY_DEFINES_H) /* XXX ruby-1.9.2p0 */ yarnPossess(ruby->ruby_coroutine_lock); yarnPossess(ruby->main_coroutine_lock); /* create a thread to house Ruby */ ruby->thread = yarnLaunchStack((void (*)(void *))rpmrubyThread, ruby, ruby->stack, ruby->nstack); assert(ruby->thread != NULL); /* Relay control to ruby until nothing more to do. */ ruby->more = (ruby->ac > 1); while (ruby->more) _rpmruby_main_to_ruby(ruby); /* Permit ruby thread to run without blocking. */ yarnRelease(ruby->ruby_coroutine_lock); /* Reap the ruby thread. */ ruby->thread = yarnJoin(ruby->thread); ec = 0; #endif /* HAVE_RUBY_DEFINES_H */ return ec; }
rpmioPool rpmioFreePool(rpmioPool pool) /*@globals _rpmioPool @*/ /*@modifies _rpmioPool @*/ { if (pool == NULL) { pool = _rpmioPool; _rpmioPool = NULL; } if (pool != NULL) { rpmioItem item; int count = 0; yarnPossess(pool->have); while ((item = pool->head) != NULL) { pool->head = item->pool; /* XXX pool == next */ if (item->use != NULL) item->use = yarnFreeLock(item->use); item = _free(item); count++; } yarnRelease(pool->have); pool->have = yarnFreeLock(pool->have); rpmlog(RPMLOG_DEBUG, D_("pool %s:\treused %d, alloc'd %d, free'd %d items.\n"), pool->name, pool->reused, pool->made, count); #ifdef NOTYET assert(pool->made == count); #else if (pool->made != count) rpmlog(RPMLOG_WARNING, D_("pool %s: FIXME: made %d, count %d\nNote: This is a harmless memory leak discovered while exiting, relax ...\n"), pool->name, pool->made, count); #endif (void) _free(pool); VALGRIND_DESTROY_MEMPOOL(pool); } return NULL; }
/*@null@*/ void * rpmioFreePoolItem(/*@killref@*/ /*@null@*/ rpmioItem item, const char * msg, const char * fn, unsigned ln) /*@modifies item @*/ { rpmioPool pool; if (item == NULL) return NULL; #ifdef NOTYET assert(item->pool != NULL); /* XXX (*pool->fini) is likely necessary */ #endif yarnPossess(item->use); if ((pool = item->pool) != NULL && pool->flags && msg != NULL) { const char * imsg = (pool->dbg ? (*pool->dbg)((void *)item) : ""); /*@-modfilesys@*/ fprintf(stderr, "--> %s %p -- %ld %s at %s:%u%s\n", pool->name, item, yarnPeekLock(item->use), msg, fn, ln, imsg); /*@=modfilesys@*/ } if (yarnPeekLock(item->use) <= 1L) { if (pool != NULL && pool->fini != NULL) (*pool->fini) ((void *)item); VALGRIND_MEMPOOL_FREE(pool, item + 1); item = rpmioPutPool(item); } else yarnTwist(item->use, BY, -1); /*@-retalias@*/ /* XXX returning the deref'd item is used to detect nrefs = 0 */ return (void *) item; /*@=retalias@*/ }
void rpmzLogAdd(rpmzLog zlog, const char *fmt, ...) { rpmzMsg me; struct timeval now; va_list ap; char msg[_RPMZLOG_MAXMSG]; int xx; if (zlog == NULL) return; xx = gettimeofday(&now, NULL); me = (rpmzMsg) xmalloc(sizeof(*me)); me->when = now; va_start(ap, fmt); xx = vsnprintf(msg, sizeof(msg)-1, fmt, ap); va_end(ap); msg[sizeof(msg)-1] = '\0'; /*@-mustfreeonly@*/ me->msg = (char *) xmalloc(strlen(msg) + 1); /*@=mustfreeonly@*/ strcpy(me->msg, msg); /*@-mustfreeonly@*/ me->next = NULL; /*@=mustfreeonly@*/ assert(zlog->_item.use != NULL); yarnPossess(zlog->_item.use); *zlog->msg_tail = me; zlog->msg_tail = &me->next; zlog->msg_count++; yarnRelease(zlog->_item.use); }
/* puts the Ruby coroutine in control */ static void _rpmruby_main_to_ruby(rpmruby ruby) { rpmzLog zlog = ruby->zlog; yarnRelease(ruby->ruby_coroutine_lock); yarnPossess(ruby->main_coroutine_lock); if (_rpmruby_debug < 0) Trace((zlog, "-> %s", __FUNCTION__)); }
/* puts the main C program in control */ static unsigned long _rpmruby_ruby_to_main(rpmruby ruby, unsigned long self) { rpmzLog zlog = ruby->zlog; yarnRelease(ruby->main_coroutine_lock); yarnPossess(ruby->ruby_coroutine_lock); if (_rpmruby_debug < 0) Trace((zlog, "<- %s", __FUNCTION__)); return Qnil; }
rpmzLog rpmzLogLink(rpmzLog zlog) { long nrefs; if (zlog == NULL) return NULL; yarnPossess(zlog->_item.use); nrefs = yarnPeekLock(zlog->_item.use); if (_rpmzlog_debug) fprintf(stderr, " ++ zlog %p[%ld]\n", zlog, nrefs+1); yarnTwist(zlog->_item.use, BY, 1); return zlog; }
/*@-internalglobs@*/ rpmioItem rpmioLinkPoolItem(rpmioItem item, const char * msg, const char * fn, unsigned ln) { rpmioPool pool; if (item == NULL) return NULL; yarnPossess(item->use); if ((pool = item->pool) != NULL && pool->flags && msg != NULL) { const char * imsg = (pool->dbg ? (*pool->dbg)((void *)item) : ""); /*@-modfilesys@*/ fprintf(stderr, "--> %s %p ++ %ld %s at %s:%u%s\n", pool->name, item, yarnPeekLock(item->use)+1, msg, fn, ln, imsg); /*@=modfilesys@*/ } yarnTwist(item->use, BY, 1); return item; }
rpmzLog rpmzLogFree(rpmzLog zlog) { long nrefs; rpmzMsg me; if (zlog == NULL) return NULL; yarnPossess(zlog->_item.use); nrefs = yarnPeekLock(zlog->_item.use); if (_rpmzlog_debug) fprintf(stderr, " -- zlog %p[%ld]\n", zlog, nrefs); #ifdef NOTYET assert(nrefs > 0); #else if (nrefs <= 0) fprintf(stderr, "==> FIXME: %s: zlog %p[%ld]\n", __FUNCTION__, zlog, nrefs); #endif if (nrefs == 1) { yarnLock use = zlog->_item.use; if (zlog->msg_tail != NULL) { while ((me = zlog->msg_head) != NULL) { zlog->msg_head = me->next; me->msg = _free(me->msg); /*@-compdestroy@*/ me = _free(me); /*@=compdestroy@*/ zlog->msg_count--; } #ifdef NOTYET assert(zlog->msg_count == 0); #else if (zlog->msg_count != 0) fprintf(stderr, "==> FIXME: %s: zlog %p[%ld] count %d\n", __FUNCTION__, zlog, nrefs, zlog->msg_count); #endif zlog->msg_count = 0; zlog->msg_tail = NULL; } zlog = _free(zlog); yarnTwist(use, BY, -1); use = yarnFreeLock(use); } else yarnTwist(zlog->_item.use, BY, -1); return NULL; }
/*@-internalglobs@*/ rpmioItem rpmioUnlinkPoolItem(rpmioItem item, const char * msg, const char * fn, unsigned ln) { rpmioPool pool; if (item == NULL) return NULL; yarnPossess(item->use); if ((pool = item->pool) != NULL && pool->flags && msg != NULL) { const char * imsg = (pool->dbg ? (*pool->dbg)((void *)item) : ""); /*@-modfilesys@*/ fprintf(stderr, "--> %s %p -- %ld %s at %s:%u%s\n", pool->name, item, yarnPeekLock(item->use), msg, fn, ln, imsg); /*@=modfilesys@*/ } yarnTwist(item->use, BY, -1); /*@-retalias@*/ /* XXX returning the deref'd item is used to detect nrefs = 0 */ return item; /*@=retalias@*/ }
/*@-internalglobs@*/ rpmioItem rpmioGetPool(rpmioPool pool, size_t size) { rpmioItem item; if (pool != NULL) { /* if can't create any more, wait for a space to show up */ yarnPossess(pool->have); if (pool->limit == 0) yarnWaitFor(pool->have, NOT_TO_BE, 0); /* if a space is available, pull it from the list and return it */ if (pool->head != NULL) { item = pool->head; pool->head = item->pool; /* XXX pool == next */ if (pool->head == NULL) pool->tail = &pool->head; pool->reused++; item->pool = pool; /* remember the pool this belongs to */ yarnTwist(pool->have, BY, -1); /* one less in pool */ VALGRIND_MEMPOOL_ALLOC(pool, item + 1, size - sizeof(struct rpmioItem_s)); return item; } /* nothing available, don't want to wait, make a new item */ assert(pool->limit != 0); if (pool->limit > 0) pool->limit--; pool->made++; yarnRelease(pool->have); } item = xcalloc(1, size); item->use = yarnNewLock(0); /* XXX newref? */ item->pool = pool; VALGRIND_MEMPOOL_ALLOC(pool, item + 1, size - sizeof(struct rpmioItem_s)); return item; }
static rpmvf rpmvfFree(/*@only@*/ rpmvf vf) /*@modifies vf @*/ { if (vf) { #ifdef NOTYET yarnPossess(vf->_item.use); if (yarnPeekLock(vf->_item.use) <= 1L) { yarnLock use = vf->_item.use; vf->fn = _free(vf->fn); vf = _free(vf); yarnTwist(use, TO, 0); use = yarnFreeLock(use); } else yarnTwist(vf->_item.use, BY, -1); #else vf->fn = _free(vf->fn); vf = _free(vf); #endif } return NULL; }
/*@-internalglobs@*/ rpmioItem rpmioPutPool(rpmioItem item) { rpmioPool pool; if ((pool = item->pool) != NULL) { yarnPossess(pool->have); item->pool = NULL; /* XXX pool == next */ *pool->tail = item; pool->tail = (void *)&item->pool;/* XXX pool == next */ yarnTwist(pool->have, BY, 1); if (item->use != NULL) yarnTwist(item->use, TO, 0); return NULL; } if (item->use != NULL) { yarnTwist(item->use, TO, 0); item->use = yarnFreeLock(item->use); } (void) _free(item); return NULL; }
/** * * Pull entry from trace log and print it, return false if empty. * */ static int rpmzMsgShow(/*@null@*/ rpmzLog zlog, /*@null@*/ FILE * fp) /*@globals fileSystem, internalState @*/ /*@modifies zlog, *fp, fileSystem, internalState @*/ { rpmzMsg me; struct timeval diff; if (zlog == NULL) return 0; if (fp == NULL) fp = stderr; yarnPossess(zlog->_item.use); if (zlog->msg_tail == NULL || (me = zlog->msg_head) == NULL) { yarnRelease(zlog->_item.use); return 0; } zlog->msg_head = me->next; if (me->next == NULL) zlog->msg_tail = &zlog->msg_head; zlog->msg_count--; yarnRelease(zlog->_item.use); diff.tv_usec = me->when.tv_usec - zlog->start.tv_usec; diff.tv_sec = me->when.tv_sec - zlog->start.tv_sec; if (diff.tv_usec < 0) { diff.tv_usec += 1000000L; diff.tv_sec--; } fprintf(fp, "trace %ld.%06ld %s\n", (long)diff.tv_sec, (long)diff.tv_usec, me->msg); (void) fflush(fp); me->msg = _free(me->msg); me = _free(me); return 1; }