/* * create connection pool */ static POOL_CONNECTION_POOL_SLOT *create_cp(POOL_CONNECTION_POOL_SLOT *cp, int slot) { BackendInfo *b = &pool_config->backend_desc->backend_info[slot]; int fd; if (*b->backend_hostname == '/') { fd = connect_unix_domain_socket(slot, TRUE); } else { fd = connect_inet_domain_socket(slot, TRUE); } if (fd < 0) { pool_error("connection to %s(%d) failed", b->backend_hostname, b->backend_port); return NULL; } cp->sp = NULL; cp->con = pool_open(fd); cp->closetime = 0; return cp; }
int wmain(int argc, wchar_t *argv[]) { STARTW(argc, argv, "log_pool_win"); if (argc < 3) UT_FATAL("usage: %s op path [poolsize mode]", ut_toUTF8(argv[0])); size_t poolsize; unsigned mode; switch (argv[1][0]) { case 'c': poolsize = wcstoul(argv[3], NULL, 0) * MB; /* in megabytes */ mode = wcstoul(argv[4], NULL, 8); pool_create(argv[2], poolsize, mode); break; case 'o': pool_open(argv[2]); break; default: UT_FATAL("unknown operation"); } DONEW(NULL); }
int main(int argc, char *argv[]) { START(argc, argv, "obj_pool"); if (argc < 4) UT_FATAL("usage: %s op path layout [poolsize mode]", argv[0]); char *layout = NULL; size_t poolsize; unsigned mode; if (strcmp(argv[3], "EMPTY") == 0) layout = ""; else if (strcmp(argv[3], "NULL") != 0) layout = argv[3]; switch (argv[1][0]) { case 'c': poolsize = strtoul(argv[4], NULL, 0) * MB; /* in megabytes */ mode = strtoul(argv[5], NULL, 8); pool_create(argv[2], layout, poolsize, mode); break; case 'o': pool_open(argv[2], layout); break; default: UT_FATAL("unknown operation"); } DONE(NULL); }
int main(int argc, char *argv[]) { START(argc, argv, "blk_pool"); if (argc < 4) UT_FATAL("usage: %s op path bsize [poolsize mode]", argv[0]); size_t bsize = strtoul(argv[3], NULL, 0); size_t poolsize; unsigned mode; switch (argv[1][0]) { case 'c': poolsize = strtoul(argv[4], NULL, 0) * MB; /* in megabytes */ mode = strtoul(argv[5], NULL, 8); pool_create(argv[2], bsize, poolsize, mode); break; case 'o': pool_open(argv[2], bsize); break; default: UT_FATAL("unknown operation"); } DONE(NULL); }
static POOL_CONNECTION_POOL_SLOT *create_cp(POOL_CONNECTION_POOL_SLOT *cp, int secondary_backend) { int fd; if (secondary_backend) { if (*pool_config.secondary_backend_host_name == '\0') fd = connect_unix_domain_socket(1); else fd = connect_inet_domain_socket(1); } else { if (*pool_config.current_backend_host_name == '\0') fd = connect_unix_domain_socket(0); else fd = connect_inet_domain_socket(0); } if (fd < 0) { /* fatal error, notice to parent and exit */ notice_backend_error(!secondary_backend); exit(1); } cp->con = pool_open(fd); cp->closetime = 0; return cp; }
/** * Command redis */ static redisReply* redisCli(server_rec *s, const char *format, ...) { redisContext* ctx = pool_open(s); void *reply = NULL; if (ctx) { va_list ap; va_start(ap,format); reply = redisvCommand(ctx,format,ap); va_end(ap); pool_close(s, ctx); } return reply; }
/* * strhash_open: open string hash table. * * i) buckets size of bucket table * r) sh STRHASH structure */ STRHASH * strhash_open(int buckets) { STRHASH *sh = (STRHASH *)check_calloc(sizeof(STRHASH), 1); int i; sh->htab = (struct sh_head *)check_calloc(sizeof(struct sh_head), buckets); for (i = 0; i < buckets; i++) SLIST_INIT(&sh->htab[i]); sh->buckets = buckets; sh->pool = pool_open(); sh->entries = 0; return sh; }
/** * gfind_open: start iterator using GPATH. * * @param[in] dbpath dbpath * @param[in] local local prefix, * if NULL specified, it assumes "./"; * @param[in] target GPATH_SOURCE: only source file, * GPATH_OTHER: only other file, * GPATH_BOTH: source file + other file * @param[in] flags GPATH_NEARSORT * @return GFIND structure */ GFIND * gfind_open(const char *dbpath, const char *local, int target, int flags) { GFIND *gfind = (GFIND *)check_calloc(sizeof(GFIND), 1); gfind->dbop = dbop_open(makepath(dbpath, dbname(GPATH), NULL), 0, 0, 0); if (gfind->dbop == NULL) die("GPATH not found."); gfind->path = NULL; gfind->prefix = check_strdup(local ? local : "./"); gfind->first = 1; gfind->eod = 0; gfind->target = target; gfind->type = GPATH_SOURCE; gfind->flags = flags; gfind->path_array = NULL; gfind->version = dbop_getversion(gfind->dbop); if (gfind->version > support_version) die("GPATH seems new format. Please install the latest GLOBAL."); else if (gfind->version < support_version) die("GPATH seems older format. Please remake tag files."); /* * Nearness sort. * In fact, this timing of sort is not good for performance. * Reconsideration is needed later. */ if (gfind->flags & GPATH_NEARSORT) { const char *path = NULL; VARRAY *varray = varray_open(sizeof(char *), 100); POOL *pool = pool_open(); while ((path = gfind_read(gfind)) != NULL) { char **a = varray_append(varray); *a = pool_strdup(pool, path, 0); } if ((nearbase = get_nearbase_path()) == NULL) die("cannot get nearbase path."); qsort(varray_assign(varray, 0, 0), varray->length, sizeof(char *), compare_nearpath); gfind->path_array = varray; gfind->pool = pool; gfind->index = 0; } return gfind; }
/** * gtags_first: return first record * * @param[in] gtop #GTOP structure * @param[in] pattern tag name <br> * - may be regular expression * - may be @VAR{NULL} * @param[in] flags #GTOP_PREFIX: prefix read <br> * #GTOP_KEY: read key only <br> * #GTOP_PATH: read path only <br> * #GTOP_NOREGEX: don't use regular expression. <br> * #GTOP_IGNORECASE: ignore case distinction. <br> * #GTOP_BASICREGEX: use basic regular expression. <br> * #GTOP_NOSORT: don't sort * @return record */ GTP * gtags_first(GTOP *gtop, const char *pattern, int flags) { int dbflags = 0; int regflags = 0; char prefix[IDENTLEN]; static regex_t reg; regex_t *preg = ® const char *key = NULL; const char *tagline; /* Settlement for last time if any */ if (gtop->path_hash) { strhash_close(gtop->path_hash); gtop->path_hash = NULL; } if (gtop->path_array) { free(gtop->path_array); gtop->path_array = NULL; } gtop->flags = flags; if (flags & GTOP_PREFIX && pattern != NULL) dbflags |= DBOP_PREFIX; if (flags & GTOP_KEY) dbflags |= DBOP_KEY; if (!(flags & GTOP_BASICREGEX)) regflags |= REG_EXTENDED; if (flags & GTOP_IGNORECASE) regflags |= REG_ICASE; /* * Get key and compiled regular expression for dbop_xxxx(). */ if (flags & GTOP_NOREGEX) { key = pattern; preg = NULL; } else if (pattern == NULL || !strcmp(pattern, ".*")) { /* * Since the regular expression '.*' matches to any record, * we take sequential read method. */ key = NULL; preg = NULL; } else if (isregex(pattern) && regcomp(preg, pattern, regflags) == 0) { const char *p; /* * If the pattern include '^' + some non regular expression * characters like '^aaa[0-9]', we take prefix read method * with the non regular expression part as the prefix. */ if (!(flags & GTOP_IGNORECASE) && *pattern == '^' && *(p = pattern + 1) && !isregexchar(*p)) { int i = 0; while (*p && !isregexchar(*p) && i < IDENTLEN) prefix[i++] = *p++; prefix[i] = '\0'; key = prefix; dbflags |= DBOP_PREFIX; } else { key = NULL; } } else { key = pattern; preg = NULL; } /* * If GTOP_PATH is set, at first, we collect all path names in a pool and * sort them. gtags_first() and gtags_next() returns one of the pool. */ if (gtop->flags & GTOP_PATH) { struct sh_entry *entry; char *p; const char *cp; unsigned long i; gtop->path_hash = strhash_open(HASHBUCKETS); /* * Pool path names. * * fid path name * +-------------------------- * |100 ./aaa/a.c * |105 ./aaa/b.c * ... */ for (tagline = dbop_first(gtop->dbop, key, preg, dbflags); tagline != NULL; tagline = dbop_next(gtop->dbop)) { VIRTUAL_GRTAGS_GSYMS_PROCESSING(gtop); /* extract file id */ p = locatestring(tagline, " ", MATCH_FIRST); if (p == NULL) die("Illegal tag record. '%s'\n", tagline); *p = '\0'; entry = strhash_assign(gtop->path_hash, tagline, 1); /* new entry: get path name and set. */ if (entry->value == NULL) { cp = gpath_fid2path(tagline, NULL); if (cp == NULL) die("GPATH is corrupted.(file id '%s' not found)", tagline); entry->value = strhash_strdup(gtop->path_hash, cp, 0); } } /* * Sort path names. * * fid path name path_array (sort) * +-------------------------- +---+ * |100 ./aaa/a.c <-------* | * |105 ./aaa/b.c <-------* | * ... ... */ gtop->path_array = (char **)check_malloc(gtop->path_hash->entries * sizeof(char *)); i = 0; for (entry = strhash_first(gtop->path_hash); entry != NULL; entry = strhash_next(gtop->path_hash)) gtop->path_array[i++] = entry->value; if (i != gtop->path_hash->entries) die("Something is wrong. 'i = %lu, entries = %lu'" , i, gtop->path_hash->entries); if (!(gtop->flags & GTOP_NOSORT)) qsort(gtop->path_array, gtop->path_hash->entries, sizeof(char *), compare_path); gtop->path_count = gtop->path_hash->entries; gtop->path_index = 0; if (gtop->path_index >= gtop->path_count) return NULL; gtop->gtp.path = gtop->path_array[gtop->path_index++]; return >op->gtp; } else if (gtop->flags & GTOP_KEY) { for (gtop->gtp.tag = dbop_first(gtop->dbop, key, preg, dbflags); gtop->gtp.tag != NULL; gtop->gtp.tag = dbop_next(gtop->dbop)) { VIRTUAL_GRTAGS_GSYMS_PROCESSING(gtop); break; } return gtop->gtp.tag ? >op->gtp : NULL; } else { if (gtop->vb == NULL) gtop->vb = varray_open(sizeof(GTP), 200); else varray_reset(gtop->vb); if (gtop->segment_pool == NULL) gtop->segment_pool = pool_open(); else pool_reset(gtop->segment_pool); if (gtop->path_hash == NULL) gtop->path_hash = strhash_open(HASHBUCKETS); else strhash_reset(gtop->path_hash); tagline = dbop_first(gtop->dbop, key, preg, dbflags); if (tagline == NULL) return NULL; /* * Dbop_next() wil read the same record again. */ dbop_unread(gtop->dbop); /* * Read a tag segment with sorting. */ segment_read(gtop); return >op->gtp_array[gtop->gtp_index++]; } }
/* * perform accept() and return new fd */ static POOL_CONNECTION *do_accept(int unix_fd, int inet_fd, struct timeval *timeout) { fd_set readmask; int fds; int save_errno; SockAddr saddr; int fd = 0; int afd; int inet = 0; POOL_CONNECTION *cp; #ifdef ACCEPT_PERFORMANCE struct timeval now1, now2; static long atime; static int cnt; #endif struct timeval *timeoutval; struct timeval tv1, tv2, tmback = {0, 0}; set_ps_display("wait for connection request", false); /* Destroy session context for just in case... */ pool_session_context_destroy(); FD_ZERO(&readmask); FD_SET(unix_fd, &readmask); if (inet_fd) FD_SET(inet_fd, &readmask); if (timeout->tv_sec == 0 && timeout->tv_usec == 0) timeoutval = NULL; else { timeoutval = timeout; tmback.tv_sec = timeout->tv_sec; tmback.tv_usec = timeout->tv_usec; gettimeofday(&tv1, NULL); #ifdef DEBUG pool_log("before select = {%d, %d}", timeoutval->tv_sec, timeoutval->tv_usec); pool_log("g:before select = {%d, %d}", tv1.tv_sec, tv1.tv_usec); #endif } fds = select(Max(unix_fd, inet_fd)+1, &readmask, NULL, NULL, timeoutval); save_errno = errno; /* check backend timer is expired */ if (backend_timer_expired) { pool_backend_timer(); backend_timer_expired = 0; } /* * following code fragment computes remaining timeout val in a * portable way. Linux does this automatically but other platforms do not. */ if (timeoutval) { gettimeofday(&tv2, NULL); tmback.tv_usec -= tv2.tv_usec - tv1.tv_usec; tmback.tv_sec -= tv2.tv_sec - tv1.tv_sec; if (tmback.tv_usec < 0) { tmback.tv_sec--; if (tmback.tv_sec < 0) { timeout->tv_sec = 0; timeout->tv_usec = 0; } else { tmback.tv_usec += 1000000; timeout->tv_sec = tmback.tv_sec; timeout->tv_usec = tmback.tv_usec; } } #ifdef DEBUG pool_log("g:after select = {%d, %d}", tv2.tv_sec, tv2.tv_usec); pool_log("after select = {%d, %d}", timeout->tv_sec, timeout->tv_usec); #endif } errno = save_errno; if (fds == -1) { if (errno == EAGAIN || errno == EINTR) return NULL; pool_error("select() failed. reason %s", strerror(errno)); return NULL; } /* timeout */ if (fds == 0) { return NULL; } if (FD_ISSET(unix_fd, &readmask)) { fd = unix_fd; } if (FD_ISSET(inet_fd, &readmask)) { fd = inet_fd; inet++; } /* * Note that some SysV systems do not work here. For those * systems, we need some locking mechanism for the fd. */ memset(&saddr, 0, sizeof(saddr)); saddr.salen = sizeof(saddr.addr); #ifdef ACCEPT_PERFORMANCE gettimeofday(&now1,0); #endif retry_accept: /* wait if recovery is started */ while (*InRecovery == 1) { pause(); } afd = accept(fd, (struct sockaddr *)&saddr.addr, &saddr.salen); save_errno = errno; /* check backend timer is expired */ if (backend_timer_expired) { pool_backend_timer(); backend_timer_expired = 0; } errno = save_errno; if (afd < 0) { if (errno == EINTR && *InRecovery) goto retry_accept; /* * "Resource temporarily unavailable" (EAGAIN or EWOULDBLOCK) * can be silently ignored. And EINTR can be ignored. */ if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) pool_error("accept() failed. reason: %s", strerror(errno)); return NULL; } #ifdef ACCEPT_PERFORMANCE gettimeofday(&now2,0); atime += (now2.tv_sec - now1.tv_sec)*1000000 + (now2.tv_usec - now1.tv_usec); cnt++; if (cnt % 100 == 0) { pool_log("cnt: %d atime: %ld", cnt, atime); } #endif /* reload config file */ if (got_sighup) { pool_get_config(get_config_file_name(), RELOAD_CONFIG); if (pool_config->enable_pool_hba) { load_hba(get_hba_file_name()); if (strcmp("", pool_config->pool_passwd)) pool_reopen_passwd_file(); } if (pool_config->parallel_mode) pool_memset_system_db_info(system_db_info->info); got_sighup = 0; } connection_count_up(); accepted = 1; if (pool_config->parallel_mode) { /* * do not accept new connection if any of DB node or SystemDB is down when operating in * parallel mode */ int i; for (i=0;i<NUM_BACKENDS;i++) { if (BACKEND_INFO(i).backend_status == CON_DOWN || SYSDB_STATUS == CON_DOWN) { StartupPacket *sp; char *msg = "pgpool is not available in parallel query mode"; if (SYSDB_STATUS == CON_DOWN) pool_log("Cannot accept() new connection. SystemDB is down"); else pool_log("Cannot accept() new connection. %d th backend is down", i); if ((cp = pool_open(afd)) == NULL) { close(afd); child_exit(1); } sp = read_startup_packet(cp); if (sp == NULL) { /* failed to read the startup packet. return to the accept() loop */ pool_close(cp); child_exit(1); } pool_debug("do_accept: send error message to frontend"); if (sp->major == PROTO_MAJOR_V3) { char buf[256]; if (SYSDB_STATUS == CON_DOWN) snprintf(buf, sizeof(buf), "SystemDB is down"); else snprintf(buf, sizeof(buf), "%d th backend is down", i); pool_send_error_message(cp, sp->major, "08S01", msg, buf, ((SYSDB_STATUS == CON_DOWN) ? "repair the SystemDB and restart pgpool" : "repair the backend and restart pgpool"), __FILE__, __LINE__); } else { pool_send_error_message(cp, sp->major, 0, msg, "", "", "", 0); } pool_close(cp); child_exit(1); } } } else { /* * do not accept new connection if all DB nodes are down when operating in * non parallel mode */ int i; int found = 0; for (i=0;i<NUM_BACKENDS;i++) { if (VALID_BACKEND(i)) { found = 1; } } if (found == 0) { pool_log("Cannot accept() new connection. all backends are down"); child_exit(1); } } pool_debug("I am %d accept fd %d", getpid(), afd); pool_getnameinfo_all(&saddr, remote_host, remote_port); snprintf(remote_ps_data, sizeof(remote_ps_data), remote_port[0] == '\0' ? "%s" : "%s(%s)", remote_host, remote_port); set_ps_display("accept connection", false); /* log who is connecting */ if (pool_config->log_connections) { pool_log("connection received: host=%s%s%s", remote_host, remote_port[0] ? " port=" : "", remote_port); } /* set NODELAY and KEEPALIVE options if INET connection */ if (inet) { int on = 1; if (setsockopt(afd, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof(on)) < 0) { pool_error("do_accept: setsockopt() failed: %s", strerror(errno)); close(afd); return NULL; } if (setsockopt(afd, SOL_SOCKET, SO_KEEPALIVE, (char *) &on, sizeof(on)) < 0) { pool_error("do_accept: setsockopt() failed: %s", strerror(errno)); close(afd); return NULL; } } if ((cp = pool_open(afd)) == NULL) { close(afd); return NULL; } /* save ip address for hba */ memcpy(&cp->raddr, &saddr, sizeof(SockAddr)); if (cp->raddr.addr.ss_family == 0) cp->raddr.addr.ss_family = AF_UNIX; return cp; }
/* * create a persistent connection */ POOL_CONNECTION_POOL_SLOT *make_persistent_db_connection( char *hostname, int port, char *dbname, char *user, char *password, bool retry) { POOL_CONNECTION_POOL_SLOT *cp; int fd; #define MAX_USER_AND_DATABASE 1024 /* V3 startup packet */ typedef struct { int protoVersion; char data[MAX_USER_AND_DATABASE]; } StartupPacket_v3; static StartupPacket_v3 *startup_packet; int len, len1; int status; cp = malloc(sizeof(POOL_CONNECTION_POOL_SLOT)); if (cp == NULL) { pool_error("make_persistent_db_connection: could not allocate memory"); return NULL; } memset(cp, 0, sizeof(POOL_CONNECTION_POOL_SLOT)); startup_packet = malloc(sizeof(*startup_packet)); if (startup_packet == NULL) { pool_error("make_persistent_db_connection: could not allocate memory"); return NULL; } memset(startup_packet, 0, sizeof(*startup_packet)); startup_packet->protoVersion = htonl(0x00030000); /* set V3 proto major/minor */ /* * create socket */ if (*hostname == '/') { fd = connect_unix_domain_socket_by_port(port, hostname, retry); } else { fd = connect_inet_domain_socket_by_port(hostname, port, retry); } if (fd < 0) { pool_error("make_persistent_db_connection: connection to %s(%d) failed", hostname, port); return NULL; } cp->con = pool_open(fd); cp->closetime = 0; cp->con->isbackend = 1; pool_ssl_negotiate_clientserver(cp->con); /* * build V3 startup packet */ len = snprintf(startup_packet->data, sizeof(startup_packet->data), "user") + 1; len1 = snprintf(&startup_packet->data[len], sizeof(startup_packet->data)-len, "%s", user) + 1; if (len1 >= (sizeof(startup_packet->data)-len)) { pool_error("make_persistent_db_connection: too long user name"); return NULL; } len += len1; len1 = snprintf(&startup_packet->data[len], sizeof(startup_packet->data)-len, "database") + 1; if (len1 >= (sizeof(startup_packet->data)-len)) { pool_error("make_persistent_db_connection: too long user name"); return NULL; } len += len1; len1 = snprintf(&startup_packet->data[len], sizeof(startup_packet->data)-len, "%s", dbname) + 1; if (len1 >= (sizeof(startup_packet->data)-len)) { pool_error("make_persistent_db_connection: too long database name"); return NULL; } len += len1; startup_packet->data[len++] = '\0'; cp->sp = malloc(sizeof(StartupPacket)); if (cp->sp == NULL) { pool_error("make_persistent_db_connection: could not allocate memory"); return NULL; } cp->sp->startup_packet = (char *)startup_packet; cp->sp->len = len + 4; cp->sp->major = 3; cp->sp->minor = 0; cp->sp->database = strdup(dbname); if (cp->sp->database == NULL) { pool_error("make_persistent_db_connection: could not allocate memory"); return NULL; } cp->sp->user = strdup(user); if (cp->sp->user == NULL) { pool_error("make_persistent_db_connection: could not allocate memory"); return NULL; } /* * send startup packet */ status = send_startup_packet(cp); if (status) { pool_error("make_persistent_db_connection: send_startup_packet failed"); return NULL; } /* * do authentication */ if (s_do_auth(cp, password)) { pool_error("make_persistent_db_connection: s_do_auth failed"); return NULL; } return cp; }
/* * process cancel request */ void cancel_request(CancelPacket *sp) { int len; int fd; POOL_CONNECTION *con; int i,j,k; ConnectionInfo *c = NULL; CancelPacket cp; bool found = false; pool_debug("Cancel request received"); /* look for cancel key from shmem info */ for (i=0;i<pool_config->num_init_children;i++) { for (j=0;j<pool_config->max_pool;j++) { for (k=0;k<NUM_BACKENDS;k++) { c = pool_coninfo(i, j, k); pool_debug("con_info: address:%p database:%s user:%s pid:%d key:%d i:%d", c, c->database, c->user, ntohl(c->pid), ntohl(c->key),i); if (c->pid == sp->pid && c->key == sp->key) { pool_debug("found pid:%d key:%d i:%d",ntohl(c->pid), ntohl(c->key),i); c = pool_coninfo(i, j, 0); found = true; goto found; } } } } found: if (!found) { pool_error("cancel_request: invalid cancel key: pid:%d key:%d",ntohl(sp->pid), ntohl(sp->key)); return; /* invalid key */ } for (i=0;i<NUM_BACKENDS;i++,c++) { if (!VALID_BACKEND(i)) continue; if (*(BACKEND_INFO(i).backend_hostname) == '/') fd = connect_unix_domain_socket(i, TRUE); else fd = connect_inet_domain_socket(i, TRUE); if (fd < 0) { pool_error("Could not create socket for sending cancel request for backend %d", i); return; } con = pool_open(fd); if (con == NULL) return; len = htonl(sizeof(len) + sizeof(CancelPacket)); pool_write(con, &len, sizeof(len)); cp.protoVersion = sp->protoVersion; cp.pid = c->pid; cp.key = c->key; pool_log("cancel_request: canceling backend pid:%d key: %d", ntohl(cp.pid),ntohl(cp.key)); if (pool_write_and_flush(con, &cp, sizeof(CancelPacket)) < 0) pool_error("Could not send cancel request packet for backend %d", i); pool_close(con); /* * this is needed to ensure that the next DB node executes the * query supposed to be canceled. */ sleep(1); } }
/** * gtags_first: return first record * * @param[in] gtop #GTOP structure * @param[in] pattern tag name <br> * - may be regular expression * - may be @VAR{NULL} * @param[in] flags #GTOP_PREFIX: prefix read <br> * #GTOP_KEY: read key only <br> * #GTOP_PATH: read path only <br> * #GTOP_NOREGEX: don't use regular expression. <br> * #GTOP_IGNORECASE: ignore case distinction. <br> * #GTOP_BASICREGEX: use basic regular expression. <br> * #GTOP_NOSORT: don't sort * @return record */ GTP * gtags_first(GTOP *gtop, const char *pattern, int flags) { int regflags = 0; static regex_t reg; const char *tagline; STATIC_STRBUF(regex); strbuf_clear(regex); gtop->preg = ® gtop->key = NULL; gtop->prefix = NULL; gtop->flags = flags; gtop->dbflags = 0; gtop->readcount = 1; /* Settlement for last time if any */ if (gtop->path_hash) { strhash_close(gtop->path_hash); gtop->path_hash = NULL; } if (gtop->path_array) { free(gtop->path_array); gtop->path_array = NULL; } if (flags & GTOP_KEY) gtop->dbflags |= DBOP_KEY; if (!(flags & GTOP_BASICREGEX)) regflags |= REG_EXTENDED; /* * decide a read method */ if (pattern == NULL) gtop->preg = NULL; else if (pattern[0] == 0) return NULL; else if (!strcmp(pattern, ".*") || !strcmp(pattern, "^.*$") || !strcmp(pattern, "^") || !strcmp(pattern, "$") || !strcmp(pattern, "^.*") || !strcmp(pattern, ".*$")) { /* * Since these regular expressions match to any record, * we take sequential read method. */ gtop->preg = NULL; } else if (flags & GTOP_IGNORECASE) { regflags |= REG_ICASE; if (!isregex(pattern) || flags & GTOP_NOREGEX) { gtop->prefix = get_prefix(pattern, flags); if (gtop->openflags & GTAGS_DEBUG) if (gtop->prefix != NULL) fprintf(stderr, "Using prefix: %s\n", gtop->prefix); if (gtop->prefix == NULL) die("gtags_first: impossible (1)."); strbuf_putc(regex, '^'); strbuf_puts(regex, pattern); if (!(flags & GTOP_PREFIX)) strbuf_putc(regex, '$'); } else if (*pattern == '^' && (gtop->prefix = get_prefix(pattern, flags)) != NULL) { if (gtop->openflags & GTAGS_DEBUG) fprintf(stderr, "Using prefix: %s\n", gtop->prefix); strbuf_puts(regex, pattern); } else { strbuf_puts(regex, pattern); } } else { if (!isregex(pattern) || flags & GTOP_NOREGEX) { if (flags & GTOP_PREFIX) gtop->dbflags |= DBOP_PREFIX; gtop->key = pattern; gtop->preg = NULL; } else if (*pattern == '^' && (gtop->key = get_prefix(pattern, flags)) != NULL) { if (gtop->openflags & GTAGS_DEBUG) fprintf(stderr, "Using prefix: %s\n", gtop->key); gtop->dbflags |= DBOP_PREFIX; gtop->preg = NULL; } else { strbuf_puts(regex, pattern); } } if (gtop->prefix) { if (gtop->key) die("gtags_first: impossible (2)."); gtop->key = gtop->prefix; gtop->dbflags |= DBOP_PREFIX; } if (strbuf_getlen(regex) > 0) { if (gtop->preg == NULL) die("gtags_first: impossible (3)."); if (regcomp(gtop->preg, strbuf_value(regex), regflags) != 0) die("invalid regular expression."); } /* * If GTOP_PATH is set, at first, we collect all path names in a pool and * sort them. gtags_first() and gtags_next() returns one of the pool. */ if (gtop->flags & GTOP_PATH) { struct sh_entry *entry; char *p; const char *cp; unsigned long i; gtop->path_hash = strhash_open(HASHBUCKETS); /* * Pool path names. * * fid path name * +-------------------------- * |100 ./aaa/a.c * |105 ./aaa/b.c * ... */ again0: for (tagline = dbop_first(gtop->dbop, gtop->key, gtop->preg, gtop->dbflags); tagline != NULL; tagline = dbop_next(gtop->dbop)) { VIRTUAL_GRTAGS_GSYMS_PROCESSING(gtop); /* extract file id */ p = locatestring(tagline, " ", MATCH_FIRST); if (p == NULL) die("Invalid tag record. '%s'\n", tagline); *p = '\0'; entry = strhash_assign(gtop->path_hash, tagline, 1); /* new entry: get path name and set. */ if (entry->value == NULL) { cp = gpath_fid2path(tagline, NULL); if (cp == NULL) die("GPATH is corrupted.(file id '%s' not found)", tagline); entry->value = strhash_strdup(gtop->path_hash, cp, 0); } } if (gtop->prefix && gtags_restart(gtop)) goto again0; /* * Sort path names. * * fid path name path_array (sort) * +-------------------------- +---+ * |100 ./aaa/a.c <-------* | * |105 ./aaa/b.c <-------* | * ... ... */ gtop->path_array = (char **)check_malloc(gtop->path_hash->entries * sizeof(char *)); i = 0; for (entry = strhash_first(gtop->path_hash); entry != NULL; entry = strhash_next(gtop->path_hash)) gtop->path_array[i++] = entry->value; if (i != gtop->path_hash->entries) die("Something is wrong. 'i = %lu, entries = %lu'" , i, gtop->path_hash->entries); if (!(gtop->flags & GTOP_NOSORT)) qsort(gtop->path_array, gtop->path_hash->entries, sizeof(char *), compare_path); gtop->path_count = gtop->path_hash->entries; gtop->path_index = 0; if (gtop->path_index >= gtop->path_count) return NULL; gtop->gtp.path = gtop->path_array[gtop->path_index++]; return >op->gtp; } else if (gtop->flags & GTOP_KEY) { again1: for (gtop->gtp.tag = dbop_first(gtop->dbop, gtop->key, gtop->preg, gtop->dbflags); gtop->gtp.tag != NULL; gtop->gtp.tag = dbop_next(gtop->dbop)) { VIRTUAL_GRTAGS_GSYMS_PROCESSING(gtop); break; } if (gtop->gtp.tag == NULL) { if (gtop->prefix && gtags_restart(gtop)) goto again1; } return gtop->gtp.tag ? >op->gtp : NULL; } else { if (gtop->vb == NULL) gtop->vb = varray_open(sizeof(GTP), 200); else varray_reset(gtop->vb); if (gtop->segment_pool == NULL) gtop->segment_pool = pool_open(); else pool_reset(gtop->segment_pool); if (gtop->path_hash == NULL) gtop->path_hash = strhash_open(HASHBUCKETS); else strhash_reset(gtop->path_hash); again2: tagline = dbop_first(gtop->dbop, gtop->key, gtop->preg, gtop->dbflags); if (tagline == NULL) { if (gtop->prefix && gtags_restart(gtop)) goto again2; return NULL; } /* * Dbop_next() wil read the same record again. */ dbop_unread(gtop->dbop); /* * Read a tag segment with sorting. */ segment_read(gtop); return >op->gtp_array[gtop->gtp_index++]; } }
/** @brief Called by the standard allocate buffer, it implements a base functionality. * * This function can be overriden if the allocation of the buffer is not a simply alloc call. * The parameters are the same as the standard function, except for the handle of the port * instead of the handler of the component * When the buffers needed by this port are all assigned or allocated, the variable * bIsFullOfBuffers becomes equal to OMX_TRUE */ OMX_ERRORTYPE videoenc_port_AllocateBuffer( omx_base_PortType *openmaxStandPort, OMX_BUFFERHEADERTYPE **pBuffer, OMX_U32 nPortIndex, OMX_PTR pAppPrivate, OMX_U32 nSizeBytes) { unsigned int i; OMX_ERRORTYPE err = OMX_ErrorNone; OMX_COMPONENTTYPE *omxComponent = openmaxStandPort->standCompContainer; omx_videoenc_PortType *omx_videoenc_Port = (omx_videoenc_PortType *)openmaxStandPort; omx_base_component_PrivateType *omx_base_component_Private = (omx_base_component_PrivateType *)omxComponent->pComponentPrivate; OMX_BUFFERHEADERTYPE *pBufferStorage_ACTEXT = NULL; OMX_VCE_Buffers_List *pBuffersMng_List= &(omx_videoenc_Port->BuffersMng_List); DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, omx_videoenc_Port); if (nPortIndex != omx_videoenc_Port->sPortParam.nPortIndex) { return OMX_ErrorBadPortIndex; } if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(omx_videoenc_Port)) { return OMX_ErrorBadPortIndex; } if (omx_base_component_Private->transientState != OMX_TransStateLoadedToIdle) { if (!omx_videoenc_Port->bIsTransientToEnabled) { DEBUG(DEB_LEV_ERR, "In %s: The port is not allowed to receive buffers\n", __func__); return OMX_ErrorIncorrectStateTransition; } } if(nSizeBytes < omx_videoenc_Port->sPortParam.nBufferSize) { DEBUG(DEB_LEV_ERR, "In %s: Requested Buffer Size %d is less than Minimum Buffer Size %d\n", __func__, nSizeBytes, omx_videoenc_Port->sPortParam.nBufferSize); return OMX_ErrorIncorrectStateTransition; } if(omx_videoenc_Port->ringbuffer == OMX_TRUE && nPortIndex == OMX_BASE_FILTER_OUTPUTPORT_INDEX) { /* open ringbuffer pool */ int buffsize = omx_videoenc_Port->ringbuf_framesize * omx_videoenc_Port->sPortParam.nBufferCountActual; if(omx_videoenc_Port->bufferpool != NULL) { if(buffsize > get_poolsize(omx_videoenc_Port->bufferpool)) { pool_dispose(omx_videoenc_Port->bufferpool); omx_videoenc_Port->bufferpool = NULL; if(pool_open(buffsize, &omx_videoenc_Port->bufferpool)) { DEBUG(DEB_LEV_ERR, "In %s: The port is not allowed to receive buffers %x\n", __func__, buffsize); return OMX_ErrorInsufficientResources; } } } else { if( pool_open(buffsize, &omx_videoenc_Port->bufferpool) ) { DEBUG(DEB_LEV_ERR, "In %s: The port is not allowed to receive buffers %x\n", __func__, buffsize); return OMX_ErrorInsufficientResources; } } } for(i=0; i < omx_videoenc_Port->sPortParam.nBufferCountActual; i++) { if (omx_videoenc_Port->bBufferStateAllocated[i] == BUFFER_FREE) { omx_videoenc_Port->pInternalBufferStorage[i] = (OMX_BUFFERHEADERTYPE *)calloc(1, sizeof(OMX_BUFFERHEADERTYPE)); if (!omx_videoenc_Port->pInternalBufferStorage[i]) { return OMX_ErrorInsufficientResources; } setHeader(omx_videoenc_Port->pInternalBufferStorage[i], sizeof(OMX_BUFFERHEADERTYPE)); /* allocate the buffer */ pBufferStorage_ACTEXT = (OMX_BUFFERHEADERTYPE *)(omx_videoenc_Port->pInternalBufferStorage[i]); pBufferStorage_ACTEXT->nAllocLen = nSizeBytes; pBufferStorage_ACTEXT->pPlatformPrivate = omx_videoenc_Port; pBufferStorage_ACTEXT->pAppPrivate = pAppPrivate; if(nPortIndex == OMX_BASE_FILTER_OUTPUTPORT_INDEX && omx_videoenc_Port->ringbuffer == OMX_TRUE) { pBufferStorage_ACTEXT->pBuffer = get_poolbase(omx_videoenc_Port->bufferpool); if(pBufferStorage_ACTEXT->pBuffer==NULL) { DEBUG(DEB_LEV_ERR, "err!get_poolbase is NULL!\n"); free(pBufferStorage_ACTEXT); omx_videoenc_Port->pInternalBufferStorage[i] = NULL; return OMX_ErrorInsufficientResources; } } else { DEBUG(DEB_LEV_PARAMS, "nSizeBytes:%d\n", nSizeBytes); err = Add_AllocateBuffer_BuffersMng(pBuffersMng_List, pBufferStorage_ACTEXT, omx_videoenc_Port->bIsStoreMediaData, nSizeBytes); if( err != OMX_ErrorNone) { DEBUG(DEB_LEV_ERR,"err!Add_AllocateBuffer_BuffersMng fail!%s,%d\n", __FILE__, __LINE__); free(omx_videoenc_Port->pInternalBufferStorage[i]); omx_videoenc_Port->pInternalBufferStorage[i] = NULL; return err; } } *pBuffer = (OMX_BUFFERHEADERTYPE *)pBufferStorage_ACTEXT; omx_videoenc_Port->bBufferStateAllocated[i] = BUFFER_ALLOCATED; omx_videoenc_Port->bBufferStateAllocated[i] |= HEADER_ALLOCATED; if (omx_videoenc_Port->sPortParam.eDir == OMX_DirInput) { pBufferStorage_ACTEXT->nInputPortIndex = omx_videoenc_Port->sPortParam.nPortIndex; } else { pBufferStorage_ACTEXT->nOutputPortIndex = omx_videoenc_Port->sPortParam.nPortIndex; } omx_videoenc_Port->nNumAssignedBuffers++; DEBUG(DEB_LEV_PARAMS, "omx_videoenc_Port->nNumAssignedBuffers %i\n", (int)omx_videoenc_Port->nNumAssignedBuffers); if (omx_videoenc_Port->sPortParam.nBufferCountActual == omx_videoenc_Port->nNumAssignedBuffers) { omx_videoenc_Port->sPortParam.bPopulated = OMX_TRUE; omx_videoenc_Port->bIsFullOfBuffers = OMX_TRUE; DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s nPortIndex=%d\n", __func__, (int)nPortIndex); DEBUG(DEB_LEV_PARAMS, "pAllocSem!%s,%d,idx:%d,semval:%d\n", __func__, __LINE__, omx_videoenc_Port->sPortParam.nPortIndex, omx_videoenc_Port->pAllocSem->semval); tsem_up(omx_videoenc_Port->pAllocSem); } DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p\n", __func__, omx_videoenc_Port); return OMX_ErrorNone; } } DEBUG(DEB_LEV_ERR, "Out of %s for port %p. Error: no available buffers\n", __func__, omx_videoenc_Port); return OMX_ErrorInsufficientResources; }