T* safe_queue_t<T>::get_element(bool dequeue, long timeout) { pthread_mutex_lock(&queue_lock); T* element = NULL; // 条件不满足,等待 if (elements->size() == 0) { if (timeout < 0) { pthread_cond_wait(&queue_ready, &queue_lock); } else { timespec waittime; make_timeout(&waittime, timeout); pthread_cond_timedwait(&queue_ready, &queue_lock, &waittime); } } if (elements->size() > 0) { element = elements->front(); // 需要出队 if (dequeue) { elements->pop(); } } pthread_mutex_unlock(&queue_lock); return element; }
/* **| method: object search ( mapping params ); **| This is the preferred way of calling this method. ** **| alt: object search ( string filter ); **| alt: object search ( string filter, array attrs ); **| alt: object search ( string filter, array attrs, int attrsonly ); **| alt: object search ( string filter, array attrs, int attrsonly, int timeout ); ** **| general: search the LDAP directory for the specified entry **| (entries). The first form is the preferred one as it **| encompasses all the current and future parameters as expected **| by the underlying API. The following fields are read from the **| mapping:@nl **| **| @list **| * base - the base DN to use in this search. Overrides the **| default base DN (as set with set_base_dn) **| * scope - the search scope for this search. Overrides the **| default scope (as set with set_scope) **| * filter - the search filter. The BNF for the filter is as **| follows: **| @pre **| <filter> ::= `(' <filtercomp> `)' **| <filtercomp> ::= <and> | <or> | <not> | <simple> **| <and> ::= `&' <filterlist> **| <or> ::= `|' <filterlist> **| <not> ::= `!' <filter> **| <filterlist> ::= <filter> | <filter> <filterlist> **| <simple> ::= <attributetype> <filtertype> <attributevalue> **| <filtertype> ::= `=' | `~=' | `<=' | `>=' **| @pre_end **| * attrs - search attributes. An array of attribute types to **| return in the result. If absent, all types will be returned. **| * attrsonly - if != then the result will contain attribute **| types only - no values shall be returned. **| * timeout - the timeout, in seconds, after which the call **| should return if the search isn't finished. **| @list_end */ static void f_ldap_search(INT32 args) { char *filter; int scope; struct pike_string *base; char **attrs; int attrsonly; struct timeval *timeout; LDAPMessage *res; int ret; struct object *obj; if (!THIS->bound) Pike_error("OpenLDAP.Client: attempting operation on an unbound connection\n"); if (!args) Pike_error("OpenLDAP.Client->search() requires at least one argument\n"); if (args == 1) { switch(ARG(1).type) { case T_MAPPING: { /* the new style case */ struct svalue *val; struct mapping *m = ARG(1).u.mapping; /* * m->base */ val = low_mapping_string_lookup(m, base_str); if (!val || val->type != T_STRING) base = THIS->basedn; else base = val->u.string; /* * m->scope */ val = low_mapping_string_lookup(m, scope_str); if (!val || val->type != T_INT) scope = THIS->scope; else scope = val->u.integer; /* * m->filter */ val = low_mapping_string_lookup(m, filter_str); if (!val || val->type != T_STRING) filter = OL_DEF_FILTER; else filter = val->u.string->str; /* * m->attrs */ val = low_mapping_string_lookup(m, attrs_str); if (!val || val->type != T_ARRAY) attrs = NULL; else attrs = make_c_array(val); /* * m->attrsonly */ val = low_mapping_string_lookup(m, attrsonly_str); if (!val || val->type != T_INT) attrsonly = 0; else attrsonly = val->u.integer != 0; /* * m->timeout */ val = low_mapping_string_lookup(m, timeout_str); if (!val || val->type != T_INT) timeout = NULL; else timeout = make_timeout(val->u.integer); /*TEMPORARY*/ break; } case T_STRING: /* the old style case */ base = THIS->basedn; scope = THIS->scope; filter = ARG(1).u.string->str; attrs = NULL; attrsonly = 0; timeout = NULL; break; default: Pike_error("OpenLDAP.Client->search() with single argument requires either a mapping or a string\n"); break; } } else switch(args) { case 4: /* timeout */ if (ARG(4).type != T_INT) Pike_error("OpenLDAP.Client->search(): argument 4 must be an integer\n"); else timeout = make_timeout(ARG(4).u.integer); /* fall through */ case 3: /* attrsonly */ if (ARG(3).type != T_INT) Pike_error("OpenLDAP.Client->search(): argument 3 must be an integer\n"); else attrsonly = ARG(3).u.integer != 0; /* fall through */ case 2: /* attrs */ if (ARG(2).type != T_ARRAY) Pike_error("OpenLDAP.Client->search(): argument 2 must be an array\n"); else attrs = make_c_array(&ARG(2)); base = THIS->basedn; scope = THIS->scope; filter = ARG(1).u.string->str; attrsonly = 0; timeout = NULL; break; default: Pike_error("OpenLDAP.Client->search(): incorrect number of arguments\n"); break; } ret = timeout ? ldap_search_st(THIS->conn, base->str, scope, filter, attrs, attrsonly, timeout, &res) : ldap_search_s(THIS->conn, base->str, scope, filter, attrs, attrsonly, &res); if (ret) Pike_error("OpenLDAP.Client->search(): %s\n", ldap_err2string(ret)); pop_n_elems(args); THIS->data = res; obj = clone_object(result_program, 0); push_object(obj); if (attrs) free(attrs); }