1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722 |
- /* Net::ZooKeeper - Perl extension for Apache ZooKeeper
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #define PERL_NO_GET_CONTEXT
- #include "EXTERN.h"
- #include "perl.h"
- #include "XSUB.h"
- #include <pthread.h> /* pthread_mutex_lock(), etc. */
- #include <string.h> /* memset(), etc. */
- #include <limits.h> /* CHAR_BIT */
- #include <sys/time.h> /* gettimeofday() */
- #define THREADED
- #include <zookeeper/zookeeper.h>
- #undef THREADED
- #include "build/check_zk_version.h"
- #define PACKAGE_NAME "Net::ZooKeeper"
- #define PACKAGE_SIGNATURE 19631123
- #define STAT_PACKAGE_NAME "Net::ZooKeeper::Stat"
- #define STAT_PACKAGE_SIGNATURE 19960512
- #define WATCH_PACKAGE_NAME "Net::ZooKeeper::Watch"
- #define WATCH_PACKAGE_SIGNATURE 20050326
- #define MAX_KEY_NAME_LEN 16 /* "children_version" */
- #define NUM_ACL_ENTRY_KEYS 3
- #define NUM_KEYS 7
- #define NUM_STAT_KEYS 11
- #define NUM_WATCH_KEYS 3
- #define DEFAULT_RECV_TIMEOUT_MSEC 10000
- #define DEFAULT_DATA_BUF_LEN 1023
- #define DEFAULT_PATH_BUF_LEN 1023
- #define DEFAULT_WATCH_TIMEOUT 60000
- #define ZOO_LOG_LEVEL_OFF 0
- #ifndef strcaseEQ
- #define strcaseEQ(a,b) (!strcasecmp((a),(b)))
- #endif
- typedef struct Stat zk_stat_t;
- typedef HV* Net__ZooKeeper__Stat;
- typedef struct zk_watch_t zk_watch_t;
- struct zk_watch_t {
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- int done;
- int ret;
- int event_type;
- int event_state;
- unsigned int timeout;
- zk_watch_t *prev;
- zk_watch_t *next;
- int ref_count;
- };
- typedef HV* Net__ZooKeeper__Watch;
- typedef struct {
- zhandle_t *handle;
- zk_watch_t *first_watch;
- int data_buf_len;
- int path_buf_len;
- unsigned int watch_timeout;
- const char *hosts;
- int hosts_len;
- int last_ret;
- int last_errno;
- } zk_t;
- typedef HV* Net__ZooKeeper;
- typedef struct {
- I32 signature;
- union {
- zk_t *zk;
- zk_stat_t *stat;
- zk_watch_t *watch;
- } handle;
- } zk_handle_t;
- typedef struct {
- const char name[MAX_KEY_NAME_LEN + 1];
- U32 name_len;
- size_t offset;
- size_t size;
- U32 hash;
- } zk_key_t;
- static zk_key_t zk_acl_entry_keys[NUM_ACL_ENTRY_KEYS] = {
- {"perms", 0, 0, 0, 0},
- {"scheme", 0, 0, 0, 0},
- {"id", 0, 0, 0, 0}
- };
- static zk_key_t zk_keys[NUM_KEYS] = {
- {"data_read_len", 0, 0, 0, 0},
- {"path_read_len", 0, 0, 0, 0},
- {"watch_timeout", 0, 0, 0, 0},
- {"hosts", 0, 0, 0, 0},
- {"session_timeout", 0, 0, 0, 0},
- {"session_id", 0, 0, 0, 0},
- {"pending_watches", 0, 0, 0, 0}
- };
- static zk_key_t zk_stat_keys[NUM_STAT_KEYS] = {
- {"czxid", 0, offsetof(struct Stat, czxid),
- sizeof(((struct Stat*) 0)->czxid), 0},
- {"mzxid", 0, offsetof(struct Stat, mzxid),
- sizeof(((struct Stat*) 0)->mzxid), 0},
- {"ctime", 0, offsetof(struct Stat, ctime),
- sizeof(((struct Stat*) 0)->ctime), 0},
- {"mtime", 0, offsetof(struct Stat, mtime),
- sizeof(((struct Stat*) 0)->mtime), 0},
- {"version", 0, offsetof(struct Stat, version),
- sizeof(((struct Stat*) 0)->version), 0},
- {"children_version", 0, offsetof(struct Stat, cversion),
- sizeof(((struct Stat*) 0)->cversion), 0},
- {"acl_version", 0, offsetof(struct Stat, aversion),
- sizeof(((struct Stat*) 0)->aversion), 0},
- {"ephemeral_owner", 0, offsetof(struct Stat, ephemeralOwner),
- sizeof(((struct Stat*) 0)->ephemeralOwner), 0},
- {"data_len", 0, offsetof(struct Stat, dataLength),
- sizeof(((struct Stat*) 0)->dataLength), 0},
- {"num_children", 0, offsetof(struct Stat, numChildren),
- sizeof(((struct Stat*) 0)->numChildren), 0},
- {"children_zxid", 0, offsetof(struct Stat, pzxid),
- sizeof(((struct Stat*) 0)->pzxid), 0}
- };
- static zk_key_t zk_watch_keys[NUM_WATCH_KEYS] = {
- {"timeout", 0, 0, 0, 0},
- {"event", 0, 0, 0, 0},
- {"state", 0, 0, 0, 0}
- };
- static void _zk_watcher(zhandle_t *handle, int type, int state,
- const char *path, void *context)
- {
- zk_watch_t *watch_ctx = context;
- pthread_mutex_lock(&watch_ctx->mutex);
- watch_ctx->event_type = type;
- watch_ctx->event_state = state;
- watch_ctx->done = 1;
- pthread_cond_signal(&watch_ctx->cond);
- pthread_mutex_unlock(&watch_ctx->mutex);
- return;
- }
- static void _zk_auth_completion(int ret, const void *data)
- {
- zk_watch_t *watch_ctx = (zk_watch_t*) data;
- pthread_mutex_lock(&watch_ctx->mutex);
- watch_ctx->ret = ret;
- watch_ctx->done = 1;
- pthread_cond_signal(&watch_ctx->cond);
- pthread_mutex_unlock(&watch_ctx->mutex);
- return;
- }
- static zk_watch_t *_zk_create_watch(pTHX)
- {
- zk_watch_t *watch;
- Newxz(watch, 1, zk_watch_t);
- if (pthread_mutex_init(&watch->mutex, NULL)) {
- int save_errno = errno;
- Safefree(watch);
- errno = save_errno;
- return NULL;
- }
- if (pthread_cond_init(&watch->cond, NULL)) {
- int save_errno = errno;
- pthread_mutex_destroy(&watch->mutex);
- Safefree(watch);
- errno = save_errno;
- return NULL;
- }
- return watch;
- }
- static void _zk_destroy_watch(pTHX_ zk_watch_t *watch)
- {
- pthread_cond_destroy(&watch->cond);
- pthread_mutex_destroy(&watch->mutex);
- Safefree(watch);
- return;
- }
- static zk_watch_t *_zk_acquire_watch(pTHX)
- {
- zk_watch_t *watch = _zk_create_watch(aTHX);
- if (watch) {
- watch->ref_count = 1;
- }
- return watch;
- }
- static void _zk_release_watch(pTHX_ zk_watch_t *watch, int list)
- {
- if (list) {
- if (watch->prev) {
- watch->prev->next = watch->next;
- }
- if (watch->next) {
- watch->next->prev = watch->prev;
- }
- watch->prev = NULL;
- watch->next = NULL;
- }
- if (--watch->ref_count == 0) {
- _zk_destroy_watch(aTHX_ watch);
- }
- return;
- }
- static unsigned int _zk_release_watches(pTHX_ zk_watch_t *first_watch,
- int final)
- {
- zk_watch_t *watch = first_watch->next;
- unsigned int pending_watches = 0;
- while (watch) {
- zk_watch_t *next_watch = watch->next;
- int done = final;
- if (!final) {
- pthread_mutex_lock(&watch->mutex);
- done = watch->done;
- pthread_mutex_unlock(&watch->mutex);
- }
- if (done) {
- _zk_release_watch(aTHX_ watch, 1);
- }
- else {
- ++pending_watches;
- }
- watch = next_watch;
- }
- return pending_watches;
- }
- static void _zk_replace_watch(pTHX_ zk_handle_t *handle,
- zk_watch_t *first_watch,
- zk_watch_t *old_watch, zk_watch_t *new_watch)
- {
- zk_watch_t *next_watch;
- new_watch->timeout = old_watch->timeout;
- _zk_release_watch(aTHX_ old_watch, 0);
- /* cleanup any completed watches not tied to a handle */
- _zk_release_watches(aTHX_ first_watch, 0);
- next_watch = first_watch->next;
- new_watch->prev = first_watch;
- new_watch->next = next_watch;
- if (next_watch) {
- next_watch->prev = new_watch;
- }
- first_watch->next = new_watch;
- ++new_watch->ref_count;
- handle->handle.watch = new_watch;
- return;
- }
- static void _zk_free_acl(pTHX_ struct ACL_vector *acl)
- {
- if (acl->data) {
- Safefree(acl->data);
- }
- return;
- }
- static const char *_zk_fill_acl(pTHX_ AV *acl_arr, struct ACL_vector *acl)
- {
- I32 num_acl_entries = av_len(acl_arr) + 1;
- int i;
- Zero(acl, 1, struct ACL_vector);
- if (num_acl_entries <= 0) {
- return NULL;
- }
- else if (num_acl_entries > PERL_INT_MAX) {
- num_acl_entries = PERL_INT_MAX;
- }
- Newx(acl->data, num_acl_entries, struct ACL);
- for (i = 0; i < num_acl_entries; ++i) {
- SV **acl_entry_ptr;
- HV *acl_entry_hash;
- zk_key_t *key;
- SV **val_ptr;
- struct ACL acl_entry;
- acl_entry_ptr = av_fetch(acl_arr, i, 0);
- if (!acl_entry_ptr) {
- continue;
- }
- if (!SvROK(*acl_entry_ptr) ||
- SvTYPE(SvRV(*acl_entry_ptr)) != SVt_PVHV) {
- _zk_free_acl(aTHX_ acl);
- return "invalid ACL entry hash reference";
- }
- acl_entry_hash = (HV*) SvRV(*acl_entry_ptr);
- key = &zk_acl_entry_keys[0];
- val_ptr = hv_fetch(acl_entry_hash, key->name, key->name_len, 0);
- if (!val_ptr) {
- _zk_free_acl(aTHX_ acl);
- return "no ACL entry perms element";
- }
- acl_entry.perms = SvIV(*val_ptr);
- if (!acl_entry.perms || (acl_entry.perms & ~ZOO_PERM_ALL)) {
- _zk_free_acl(aTHX_ acl);
- return "invalid ACL entry perms";
- }
- key = &zk_acl_entry_keys[1];
- val_ptr = hv_fetch(acl_entry_hash, key->name, key->name_len, 0);
- if (!val_ptr) {
- _zk_free_acl(aTHX_ acl);
- return "no ACL entry scheme element";
- }
- acl_entry.id.scheme = SvPV_nolen(*val_ptr);
- key = &zk_acl_entry_keys[2];
- val_ptr = hv_fetch(acl_entry_hash, key->name, key->name_len, 0);
- if (!val_ptr) {
- _zk_free_acl(aTHX_ acl);
- return "no ACL entry id element";
- }
- acl_entry.id.id = SvPV_nolen(*val_ptr);
- ++acl->count;
- acl->data[i] = acl_entry;
- }
- return NULL;
- }
- static void _zk_fill_acl_entry_hash(pTHX_ struct ACL *acl_entry,
- HV *acl_entry_hash)
- {
- zk_key_t *key;
- SV *val;
- key = &zk_acl_entry_keys[0];
- val = newSViv(acl_entry->perms);
- if (!hv_store(acl_entry_hash, key->name, key->name_len, val, key->hash)) {
- SvREFCNT_dec(val);
- }
- key = &zk_acl_entry_keys[1];
- val = newSVpv(acl_entry->id.scheme, 0);
- if (!hv_store(acl_entry_hash, key->name, key->name_len, val, key->hash)) {
- SvREFCNT_dec(val);
- }
- key = &zk_acl_entry_keys[2];
- val = newSVpv(acl_entry->id.id, 0);
- if (!hv_store(acl_entry_hash, key->name, key->name_len, val, key->hash)) {
- SvREFCNT_dec(val);
- }
- return;
- }
- static zk_handle_t *_zk_check_handle_inner(pTHX_ HV *attr_hash,
- I32 package_signature)
- {
- zk_handle_t *handle = NULL;
- if (SvRMAGICAL(attr_hash)) {
- MAGIC *magic = mg_find((SV*) attr_hash, PERL_MAGIC_ext);
- if (magic) {
- handle = (zk_handle_t*) magic->mg_ptr;
- if (handle->signature != package_signature) {
- handle = NULL;
- }
- }
- }
- return handle;
- }
- static zk_handle_t *_zk_check_handle_outer(pTHX_ HV *hash, HV **attr_hash_ptr,
- const char *package_name,
- I32 package_signature)
- {
- zk_handle_t *handle = NULL;
- if (attr_hash_ptr) {
- *attr_hash_ptr = NULL;
- }
- if (SvRMAGICAL((SV*) hash)) {
- MAGIC *magic = mg_find((SV*) hash, PERL_MAGIC_tied);
- if (magic) {
- SV *attr = magic->mg_obj;
- if (SvROK(attr) && SvTYPE(SvRV(attr)) == SVt_PVHV &&
- sv_derived_from(attr, package_name)) {
- HV *attr_hash = (HV*) SvRV(attr);
- handle = _zk_check_handle_inner(aTHX_ attr_hash,
- package_signature);
- if (handle && attr_hash_ptr) {
- *attr_hash_ptr = attr_hash;
- }
- }
- }
- }
- return handle;
- }
- static zk_t *_zk_get_handle_inner(pTHX_ Net__ZooKeeper attr_hash)
- {
- zk_handle_t *handle;
- handle = _zk_check_handle_inner(aTHX_ attr_hash, PACKAGE_SIGNATURE);
- return handle ? handle->handle.zk : NULL;
- }
- static zk_t *_zk_get_handle_outer(pTHX_ Net__ZooKeeper zkh)
- {
- zk_handle_t *handle;
- handle = _zk_check_handle_outer(aTHX_ zkh, NULL, PACKAGE_NAME,
- PACKAGE_SIGNATURE);
- return handle ? handle->handle.zk : NULL;
- }
- static zk_stat_t *_zks_get_handle_inner(pTHX_ Net__ZooKeeper__Stat attr_hash)
- {
- zk_handle_t *handle;
- handle = _zk_check_handle_inner(aTHX_ attr_hash, STAT_PACKAGE_SIGNATURE);
- return handle ? handle->handle.stat : NULL;
- }
- static zk_stat_t *_zks_get_handle_outer(pTHX_ Net__ZooKeeper__Stat zksh)
- {
- zk_handle_t *handle;
- handle = _zk_check_handle_outer(aTHX_ zksh, NULL, STAT_PACKAGE_NAME,
- STAT_PACKAGE_SIGNATURE);
- return handle ? handle->handle.stat : NULL;
- }
- static zk_watch_t *_zkw_get_handle_inner(pTHX_ Net__ZooKeeper__Watch attr_hash)
- {
- zk_handle_t *handle;
- handle = _zk_check_handle_inner(aTHX_ attr_hash, WATCH_PACKAGE_SIGNATURE);
- return handle ? handle->handle.watch : NULL;
- }
- static zk_watch_t *_zkw_get_handle_outer(pTHX_ Net__ZooKeeper__Watch zkwh,
- zk_handle_t **handle_ptr)
- {
- zk_handle_t *handle;
- handle = _zk_check_handle_outer(aTHX_ zkwh, NULL, WATCH_PACKAGE_NAME,
- WATCH_PACKAGE_SIGNATURE);
- if (handle_ptr) {
- *handle_ptr = handle;
- }
- return handle ? handle->handle.watch : NULL;
- }
- MODULE = Net::ZooKeeper PACKAGE = Net::ZooKeeper PREFIX = zk_
- REQUIRE: 1.9508
- PROTOTYPES: ENABLE
- BOOT:
- {
- int i;
- for (i = 0; i < NUM_ACL_ENTRY_KEYS; ++i) {
- zk_key_t *key = &zk_acl_entry_keys[i];
- key->name_len = strlen(key->name);
- PERL_HASH(key->hash, key->name, key->name_len);
- }
- for (i = 0; i < NUM_KEYS; ++i) {
- zk_keys[i].name_len = strlen(zk_keys[i].name);
- }
- for (i = 0; i < NUM_STAT_KEYS; ++i) {
- zk_stat_keys[i].name_len = strlen(zk_stat_keys[i].name);
- }
- for (i = 0; i < NUM_WATCH_KEYS; ++i) {
- zk_watch_keys[i].name_len = strlen(zk_watch_keys[i].name);
- }
- zoo_set_log_stream(NULL);
- zoo_set_debug_level(0);
- }
- I32
- zk_constant(alias=Nullch)
- char *alias
- ALIAS:
- ZOK = ZOK
- ZSYSTEMERROR = ZSYSTEMERROR
- ZRUNTIMEINCONSISTENCY = ZRUNTIMEINCONSISTENCY
- ZDATAINCONSISTENCY = ZDATAINCONSISTENCY
- ZCONNECTIONLOSS = ZCONNECTIONLOSS
- ZMARSHALLINGERROR = ZMARSHALLINGERROR
- ZUNIMPLEMENTED = ZUNIMPLEMENTED
- ZOPERATIONTIMEOUT = ZOPERATIONTIMEOUT
- ZBADARGUMENTS = ZBADARGUMENTS
- ZINVALIDSTATE = ZINVALIDSTATE
- ZAPIERROR = ZAPIERROR
- ZNONODE = ZNONODE
- ZNOAUTH = ZNOAUTH
- ZBADVERSION = ZBADVERSION
- ZNOCHILDRENFOREPHEMERALS = ZNOCHILDRENFOREPHEMERALS
- ZNODEEXISTS = ZNODEEXISTS
- ZNOTEMPTY = ZNOTEMPTY
- ZSESSIONEXPIRED = ZSESSIONEXPIRED
- ZINVALIDCALLBACK = ZINVALIDCALLBACK
- ZINVALIDACL = ZINVALIDACL
- ZAUTHFAILED = ZAUTHFAILED
- ZCLOSING = ZCLOSING
- ZNOTHING = ZNOTHING
- ZOO_EPHEMERAL = ZOO_EPHEMERAL
- ZOO_SEQUENCE = ZOO_SEQUENCE
- ZOO_PERM_READ = ZOO_PERM_READ
- ZOO_PERM_WRITE = ZOO_PERM_WRITE
- ZOO_PERM_CREATE = ZOO_PERM_CREATE
- ZOO_PERM_DELETE = ZOO_PERM_DELETE
- ZOO_PERM_ADMIN = ZOO_PERM_ADMIN
- ZOO_PERM_ALL = ZOO_PERM_ALL
- ZOO_CREATED_EVENT = ZOO_CREATED_EVENT
- ZOO_DELETED_EVENT = ZOO_DELETED_EVENT
- ZOO_CHANGED_EVENT = ZOO_CHANGED_EVENT
- ZOO_CHILD_EVENT = ZOO_CHILD_EVENT
- ZOO_SESSION_EVENT = ZOO_SESSION_EVENT
- ZOO_NOTWATCHING_EVENT = ZOO_NOTWATCHING_EVENT
- ZOO_EXPIRED_SESSION_STATE = ZOO_EXPIRED_SESSION_STATE
- ZOO_AUTH_FAILED_STATE = ZOO_AUTH_FAILED_STATE
- ZOO_CONNECTING_STATE = ZOO_CONNECTING_STATE
- ZOO_ASSOCIATING_STATE = ZOO_ASSOCIATING_STATE
- ZOO_CONNECTED_STATE = ZOO_CONNECTED_STATE
- ZOO_LOG_LEVEL_OFF = ZOO_LOG_LEVEL_OFF
- ZOO_LOG_LEVEL_ERROR = ZOO_LOG_LEVEL_ERROR
- ZOO_LOG_LEVEL_WARN = ZOO_LOG_LEVEL_WARN
- ZOO_LOG_LEVEL_INFO = ZOO_LOG_LEVEL_INFO
- ZOO_LOG_LEVEL_DEBUG = ZOO_LOG_LEVEL_DEBUG
- CODE:
- if (!ix) {
- if (!alias) {
- alias = GvNAME(CvGV(cv));
- }
- if (strEQ(alias, "ZOK")) {
- RETVAL = ZOK;
- }
- else if (strEQ(alias, "ZOO_LOG_LEVEL_OFF")) {
- RETVAL = ZOO_LOG_LEVEL_OFF;
- }
- else {
- Perl_croak(aTHX_ "unknown " PACKAGE_NAME " constant: %s",
- alias);
- }
- }
- else {
- RETVAL = ix;
- }
- OUTPUT:
- RETVAL
- AV *
- zk_acl_constant(alias=Nullch)
- char *alias
- ALIAS:
- ZOO_OPEN_ACL_UNSAFE = 1
- ZOO_READ_ACL_UNSAFE = 2
- ZOO_CREATOR_ALL_ACL = 3
- PREINIT:
- struct ACL_vector acl;
- AV *acl_arr;
- int i;
- PPCODE:
- if (!ix && !alias) {
- alias = GvNAME(CvGV(cv));
- }
- if (ix == 1 || (alias != NULL && strEQ(alias, "ZOO_OPEN_ACL_UNSAFE"))) {
- acl = ZOO_OPEN_ACL_UNSAFE;
- }
- else if (ix == 2 || (alias != NULL && strEQ(alias, "ZOO_READ_ACL_UNSAFE"))) {
- acl = ZOO_READ_ACL_UNSAFE;
- }
- else if (ix == 3 || (alias != NULL && strEQ(alias, "ZOO_CREATOR_ALL_ACL"))) {
- acl = ZOO_CREATOR_ALL_ACL;
- }
- else {
- Perl_croak(aTHX_ "unknown " PACKAGE_NAME " constant: %s", alias);
- }
- acl_arr = newAV();
- av_extend(acl_arr, acl.count);
- for (i = 0; i < acl.count; ++i) {
- HV *acl_entry_hash = newHV();
- SV *val;
- _zk_fill_acl_entry_hash(aTHX_ &acl.data[i], acl_entry_hash);
- val = newRV_noinc((SV*) acl_entry_hash);
- if (!av_store(acl_arr, i, val)) {
- SvREFCNT_dec(val);
- }
- }
- ST(0) = sv_2mortal(newRV_noinc((SV*) acl_arr));
- XSRETURN(1);
- void
- zk_set_log_level(level)
- int level
- PPCODE:
- if (level < ZOO_LOG_LEVEL_OFF || level > ZOO_LOG_LEVEL_DEBUG) {
- Perl_croak(aTHX_ "invalid log level: %d", level);
- }
- zoo_set_debug_level(level);
- XSRETURN_EMPTY;
- void
- zk_set_deterministic_conn_order(flag)
- bool flag
- PPCODE:
- zoo_deterministic_conn_order(!!flag);
- XSRETURN_EMPTY;
- void
- zk_new(package, hosts, ...)
- char *package
- char *hosts
- PREINIT:
- int recv_timeout = DEFAULT_RECV_TIMEOUT_MSEC;
- #ifdef HAVE_CYRUS_SASL_H
- zoo_sasl_params_t sasl_params = { 0 };
- const char *sasl_user = NULL;
- const char *sasl_realm = NULL;
- const char *sasl_password_file = NULL;
- int use_sasl = 0;
- #endif /* HAVE_CYRUS_SASL_H */
- const clientid_t *client_id = NULL;
- zk_t *zk;
- zk_handle_t *handle;
- HV *stash, *zk_hash, *attr_hash;
- SV *attr;
- int i;
- PPCODE:
- if (items > 2 && items % 2) {
- Perl_croak(aTHX_ "invalid number of arguments");
- }
- for (i = 2; i < items; i += 2) {
- char *key = SvPV_nolen(ST(i));
- if (strcaseEQ(key, "session_timeout")) {
- recv_timeout = SvIV(ST(i + 1));
- /* NOTE: would be nice if requirement in zookeeper_interest()
- * that recv_timeout*2 be non-negative was documented
- */
- if (recv_timeout < 0 || recv_timeout > (PERL_INT_MAX >> 1)) {
- Perl_croak(aTHX_ "invalid session timeout: %d",
- recv_timeout);
- }
- }
- else if (strcaseEQ(key, "session_id")) {
- STRLEN client_id_len;
- client_id = (const clientid_t*) SvPV(ST(i + 1), client_id_len);
- if (client_id_len != sizeof(clientid_t)) {
- Perl_croak(aTHX_ "invalid session ID");
- }
- }
- #ifdef HAVE_CYRUS_SASL_H
- else if (strcaseEQ(key, "sasl_options")) {
- SV *hash_sv = ST(i + 1);
- HV *hash;
- char *key;
- I32 key_length;
- SV *value;
- if (!SvROK(hash_sv) || SvTYPE(SvRV(hash_sv)) != SVt_PVHV) {
- Perl_croak(aTHX_ "sasl_options requires a hash reference");
- }
- hash = (HV *)SvRV(hash_sv);
- hv_iterinit(hash);
- while ((value = hv_iternextsv(hash, &key, &key_length))) {
- if (strcaseEQ(key, "service")) {
- sasl_params.service = SvPV_nolen(value);
- }
- else if (strcaseEQ(key, "host")) {
- sasl_params.host = SvPV_nolen(value);
- }
- else if (strcaseEQ(key, "mechlist")) {
- sasl_params.mechlist = SvPV_nolen(value);
- }
- else if (strcaseEQ(key, "user")) {
- sasl_user = SvPV_nolen(value);
- }
- else if (strcaseEQ(key, "realm")) {
- sasl_realm = SvPV_nolen(value);
- }
- else if (strcaseEQ(key, "password_file")) {
- sasl_password_file = SvPV_nolen(value);
- }
- }
- use_sasl = 1;
- }
- #endif /* HAVE_CYRUS_SASL_H */
- }
- Newxz(zk, 1, zk_t);
- #ifdef HAVE_CYRUS_SASL_H
- if (use_sasl) {
- /* KLUDGE: Leaks a reference count. Authen::SASL::XS does
- the same, though. TODO(ddiederen): Fix. */
- sasl_client_init(NULL);
- sasl_params.callbacks = zoo_sasl_make_basic_callbacks(sasl_user,
- sasl_realm, sasl_password_file);
- }
- zk->handle = zookeeper_init_sasl(hosts, NULL, recv_timeout,
- client_id, NULL, 0, NULL, use_sasl ? &sasl_params : NULL);
- #else
- zk->handle = zookeeper_init(hosts, NULL, recv_timeout,
- client_id, NULL, 0);
- #endif /* HAVE_CYRUS_SASL_H */
- if (!zk->handle) {
- Safefree(zk);
- XSRETURN_UNDEF;
- }
- Newxz(zk->first_watch, 1, zk_watch_t);
- zk->data_buf_len = DEFAULT_DATA_BUF_LEN;
- zk->path_buf_len = DEFAULT_PATH_BUF_LEN;
- zk->watch_timeout = DEFAULT_WATCH_TIMEOUT;
- zk->hosts_len = strlen(hosts);
- zk->hosts = savepvn(hosts, zk->hosts_len);
- Newx(handle, 1, zk_handle_t);
- handle->signature = PACKAGE_SIGNATURE;
- handle->handle.zk = zk;
- /* We use several tricks from DBI here. The attr_hash is our
- * empty inner hash; we attach extra magic to it in the form of
- * our zk_handle_t structure. Then we tie attr_hash to zk_hash,
- * our outer hash. This is what is passed around (by reference) by
- * callers.
- *
- * Most methods use _zk_get_handle_outer() which finds our inner
- * handle, then returns the zk_t structure from its extra magic
- * pointer.
- *
- * However, the tied hash methods, FETCH(), STORE(), and so forth,
- * receive an already-dereferenced inner handle hash. This is
- * because we bless both inner and outer handles into this class,
- * so when a caller's code references a hash element in our
- * outer handle, Perl detects its tied magic, looks up the
- * tied object (our inner handle) and invokes the tied hash methods
- * in its class on it. Since we blessed it into the same class
- * as the outer handle, these methods simply reside in our package.
- */
- stash = gv_stashpv(package, GV_ADDWARN);
- attr_hash = newHV();
- sv_magic((SV*) attr_hash, Nullsv, PERL_MAGIC_ext,
- (const char*) handle, 0);
- attr = sv_bless(newRV_noinc((SV*) attr_hash), stash);
- zk_hash = newHV();
- sv_magic((SV*) zk_hash, attr, PERL_MAGIC_tied, Nullch, 0);
- SvREFCNT_dec(attr);
- ST(0) = sv_bless(sv_2mortal(newRV_noinc((SV*) zk_hash)), stash);
- XSRETURN(1);
- void
- zk_DESTROY(zkh)
- Net::ZooKeeper zkh
- PREINIT:
- zk_handle_t *handle;
- HV *attr_hash;
- int ret = ZBADARGUMENTS;
- PPCODE:
- handle = _zk_check_handle_outer(aTHX_ zkh, &attr_hash,
- PACKAGE_NAME, PACKAGE_SIGNATURE);
- if (!handle) {
- handle = _zk_check_handle_inner(aTHX_ zkh, PACKAGE_SIGNATURE);
- if (handle) {
- attr_hash = zkh;
- zkh = NULL;
- }
- }
- if (handle) {
- zk_t *zk = handle->handle.zk;
- ret = zookeeper_close(zk->handle);
- /* detach all now-inactive watches still tied to handles */
- _zk_release_watches(aTHX_ zk->first_watch, 1);
- Safefree(zk->first_watch);
- Safefree(zk->hosts);
- Safefree(zk);
- Safefree(handle);
- sv_unmagic((SV*) attr_hash, PERL_MAGIC_ext);
- }
- if (zkh && attr_hash) {
- sv_unmagic((SV*) zkh, PERL_MAGIC_tied);
- }
- if (GIMME_V == G_VOID) {
- XSRETURN_EMPTY;
- }
- else if (ret == ZOK) {
- XSRETURN_YES;
- }
- else {
- XSRETURN_NO;
- }
- void
- zk_CLONE(package)
- char *package
- PPCODE:
- XSRETURN_EMPTY;
- void
- zk_CLONE_SKIP(package)
- char *package
- PPCODE:
- XSRETURN_YES;
- void
- zk_TIEHASH(package, ...)
- char *package
- PPCODE:
- Perl_croak(aTHX_ "tying hashes of class "
- PACKAGE_NAME " not supported");
- void
- zk_UNTIE(attr_hash, ref_count)
- Net::ZooKeeper attr_hash
- IV ref_count
- PPCODE:
- Perl_croak(aTHX_ "untying hashes of class "
- PACKAGE_NAME " not supported");
- void
- zk_FIRSTKEY(attr_hash)
- Net::ZooKeeper attr_hash
- PREINIT:
- zk_t *zk;
- PPCODE:
- zk = _zk_get_handle_inner(aTHX_ attr_hash);
- if (!zk) {
- Perl_croak(aTHX_ "invalid handle");
- }
- ST(0) = sv_2mortal(newSVpvn(zk_keys[0].name, zk_keys[0].name_len));
- XSRETURN(1);
- void
- zk_NEXTKEY(attr_hash, attr_key)
- Net::ZooKeeper attr_hash
- SV *attr_key
- PREINIT:
- zk_t *zk;
- char *key;
- int i;
- PPCODE:
- zk = _zk_get_handle_inner(aTHX_ attr_hash);
- if (!zk) {
- Perl_croak(aTHX_ "invalid handle");
- }
- key = SvPV_nolen(attr_key);
- for (i = 0; i < NUM_KEYS; ++i) {
- if (strcaseEQ(key, zk_keys[i].name)) {
- ++i;
- break;
- }
- }
- if (i < NUM_KEYS) {
- ST(0) = sv_2mortal(newSVpvn(zk_keys[i].name, zk_keys[i].name_len));
- XSRETURN(1);
- }
- else {
- XSRETURN_EMPTY;
- }
- void
- zk_SCALAR(attr_hash)
- Net::ZooKeeper attr_hash
- PPCODE:
- XSRETURN_YES;
- void
- zk_FETCH(attr_hash, attr_key)
- Net::ZooKeeper attr_hash
- SV *attr_key
- PREINIT:
- zk_t *zk;
- char *key;
- SV *val = NULL;
- PPCODE:
- zk = _zk_get_handle_inner(aTHX_ attr_hash);
- if (!zk) {
- Perl_croak(aTHX_ "invalid handle");
- }
- key = SvPV_nolen(attr_key);
- if (strcaseEQ(key, "data_read_len")) {
- val = newSViv(zk->data_buf_len);
- }
- else if (strcaseEQ(key, "path_read_len")) {
- val = newSViv(zk->path_buf_len);
- }
- else if (strcaseEQ(key, "watch_timeout")) {
- val = newSVuv(zk->watch_timeout);
- }
- else if (strcaseEQ(key, "hosts")) {
- val = newSVpvn(zk->hosts, zk->hosts_len);
- }
- else if (strcaseEQ(key, "session_timeout")) {
- val = newSViv(zoo_recv_timeout(zk->handle));
- }
- else if (strcaseEQ(key, "session_id")) {
- const clientid_t *client_id;
- clientid_t null_client_id;
- client_id = zoo_client_id(zk->handle);
- memset(&null_client_id, 0, sizeof(clientid_t));
- if (!memcmp(client_id, &null_client_id, sizeof(clientid_t))) {
- val = newSVpv("", 0);
- }
- else {
- val = newSVpvn((const char*) client_id, sizeof(clientid_t));
- }
- }
- else if (strcaseEQ(key, "pending_watches")) {
- /* cleanup any completed watches not tied to a handle */
- val = newSVuv(_zk_release_watches(aTHX_ zk->first_watch, 0));
- }
- if (val) {
- ST(0) = sv_2mortal(val);
- XSRETURN(1);
- }
- Perl_warn(aTHX_ "invalid element: %s", key);
- XSRETURN_UNDEF;
- void
- zk_STORE(attr_hash, attr_key, attr_val)
- Net::ZooKeeper attr_hash
- SV *attr_key
- SV *attr_val
- PREINIT:
- zk_t *zk;
- char *key;
- PPCODE:
- zk = _zk_get_handle_inner(aTHX_ attr_hash);
- if (!zk) {
- Perl_croak(aTHX_ "invalid handle");
- }
- key = SvPV_nolen(attr_key);
- if (strcaseEQ(key, "data_read_len")) {
- int val = SvIV(attr_val);
- if (val < 0) {
- Perl_croak(aTHX_ "invalid data read length: %d", val);
- }
- zk->data_buf_len = val;
- }
- else if (strcaseEQ(key, "path_read_len")) {
- int val = SvIV(attr_val);
- if (val < 0) {
- Perl_croak(aTHX_ "invalid path read length: %d", val);
- }
- zk->path_buf_len = val;
- }
- else if (strcaseEQ(key, "watch_timeout")) {
- zk->watch_timeout = SvUV(attr_val);
- }
- else {
- int i;
- for (i = 0; i < NUM_KEYS; ++i) {
- if (strcaseEQ(key, zk_keys[i].name)) {
- Perl_warn(aTHX_ "read-only element: %s", key);
- XSRETURN_EMPTY;
- }
- }
- Perl_warn(aTHX_ "invalid element: %s", key);
- }
- XSRETURN_EMPTY;
- void
- zk_EXISTS(attr_hash, attr_key)
- Net::ZooKeeper attr_hash
- SV *attr_key
- PREINIT:
- zk_t *zk;
- char *key;
- int i;
- PPCODE:
- zk = _zk_get_handle_inner(aTHX_ attr_hash);
- if (!zk) {
- Perl_croak(aTHX_ "invalid handle");
- }
- key = SvPV_nolen(attr_key);
- for (i = 0; i < NUM_KEYS; ++i) {
- if (strcaseEQ(key, zk_keys[i].name)) {
- XSRETURN_YES;
- }
- }
- XSRETURN_NO;
- void
- zk_DELETE(attr_hash, attr_key)
- Net::ZooKeeper attr_hash
- SV *attr_key
- PPCODE:
- Perl_warn(aTHX_ "deleting elements from hashes of class "
- PACKAGE_NAME " not supported");
- XSRETURN_EMPTY;
- void
- zk_CLEAR(attr_hash)
- Net::ZooKeeper attr_hash
- PPCODE:
- Perl_warn(aTHX_ "clearing hashes of class "
- PACKAGE_NAME " not supported");
- XSRETURN_EMPTY;
- SV *
- zk_get_error(zkh)
- Net::ZooKeeper zkh
- PREINIT:
- zk_t *zk;
- CODE:
- zk = _zk_get_handle_outer(aTHX_ zkh);
- if (!zk) {
- Perl_croak(aTHX_ "invalid handle");
- }
- RETVAL = newSViv(zk->last_ret);
- errno = zk->last_errno;
- OUTPUT:
- RETVAL
- void
- zk_add_auth(zkh, scheme, cert)
- Net::ZooKeeper zkh
- char *scheme
- char *cert; cert = (char *) SvPV($arg, cert_len);
- PREINIT:
- zk_t *zk;
- STRLEN cert_len;
- zk_watch_t *watch;
- int ret;
- PPCODE:
- zk = _zk_get_handle_outer(aTHX_ zkh);
- if (!zk) {
- Perl_croak(aTHX_ "invalid handle");
- }
- zk->last_ret = ZOK;
- zk->last_errno = 0;
- if (cert_len > PERL_INT_MAX) {
- Perl_croak(aTHX_ "invalid certificate length: %zu", cert_len);
- }
- watch = _zk_create_watch(aTHX);
- if (!watch) {
- /* errno will be set */
- zk->last_ret = ZSYSTEMERROR;
- zk->last_errno = errno;
- XSRETURN_NO;
- }
- errno = 0;
- ret = zoo_add_auth(zk->handle, scheme, cert, cert_len,
- _zk_auth_completion, watch);
- zk->last_ret = ret;
- zk->last_errno = errno;
- if (ret == ZOK) {
- pthread_mutex_lock(&watch->mutex);
- while (!watch->done) {
- pthread_cond_wait(&watch->cond, &watch->mutex);
- }
- pthread_mutex_unlock(&watch->mutex);
- if (watch->done) {
- ret = watch->ret;
- }
- else {
- ret = ZINVALIDSTATE;
- }
- /* errno may be set while we waited */
- zk->last_ret = ret;
- zk->last_errno = errno;
- }
- _zk_destroy_watch(aTHX_ watch);
- if (ret == ZOK) {
- XSRETURN_YES;
- }
- else {
- XSRETURN_NO;
- }
- void
- zk_create(zkh, path, buf, ...)
- Net::ZooKeeper zkh
- char *path
- char *buf; buf = (char *) SvPV($arg, buf_len);
- PREINIT:
- zk_t *zk;
- STRLEN buf_len;
- int flags = 0;
- char *path_buf;
- int path_buf_len;
- AV *acl_arr = NULL;
- struct ACL_vector acl;
- int i, ret;
- PPCODE:
- zk = _zk_get_handle_outer(aTHX_ zkh);
- if (!zk) {
- Perl_croak(aTHX_ "invalid handle");
- }
- zk->last_ret = ZOK;
- zk->last_errno = 0;
- if (items > 3 && !(items % 2)) {
- Perl_croak(aTHX_ "invalid number of arguments");
- }
- if (buf_len > PERL_INT_MAX) {
- Perl_croak(aTHX_ "invalid data length: %zu", buf_len);
- }
- path_buf_len = zk->path_buf_len;
- for (i = 3; i < items; i += 2) {
- char *key = SvPV_nolen(ST(i));
- if (strcaseEQ(key, "path_read_len")) {
- path_buf_len = SvIV(ST(i + 1));
- if (path_buf_len < 2) {
- Perl_croak(aTHX_ "invalid path read length: %d",
- path_buf_len);
- }
- }
- else if (strcaseEQ(key, "flags")) {
- flags = SvIV(ST(i + 1));
- if (flags & ~(ZOO_SEQUENCE | ZOO_EPHEMERAL)) {
- Perl_croak(aTHX_ "invalid create flags: %d", flags);
- }
- }
- else if (strcaseEQ(key, "acl")) {
- const char *err;
- if (!SvROK(ST(i + 1)) || SvTYPE(SvRV(ST(i + 1))) != SVt_PVAV) {
- Perl_croak(aTHX_ "invalid ACL array reference");
- }
- acl_arr = (AV*) SvRV(ST(i + 1));
- err = _zk_fill_acl(aTHX_ acl_arr, &acl);
- if (err) {
- Perl_croak(aTHX_ "%s", err);
- }
- }
- }
- /* NOTE: would be nice to be able to rely on null-terminated string */
- ++path_buf_len;
- Newxz(path_buf, path_buf_len, char);
- errno = 0;
- ret = zoo_create(zk->handle, path, buf, buf_len,
- (acl_arr ? &acl : NULL), flags,
- path_buf, path_buf_len);
- zk->last_ret = ret;
- zk->last_errno = errno;
- if (acl_arr) {
- _zk_free_acl(aTHX_ &acl);
- }
- if (ret == ZOK) {
- ST(0) = sv_newmortal();
- #ifdef SV_HAS_TRAILING_NUL
- sv_usepvn_flags(ST(0), path_buf, strlen(path_buf),
- SV_HAS_TRAILING_NUL);
- #else
- sv_usepvn(ST(0), path_buf, strlen(path_buf));
- #endif
- SvCUR_set(ST(0), strlen(path_buf));
- XSRETURN(1);
- }
- Safefree(path_buf);
- XSRETURN_UNDEF;
- void
- zk_delete(zkh, path, ...)
- Net::ZooKeeper zkh
- char *path
- PREINIT:
- zk_t *zk;
- int version = -1;
- int i, ret;
- PPCODE:
- zk = _zk_get_handle_outer(aTHX_ zkh);
- if (!zk) {
- Perl_croak(aTHX_ "invalid handle");
- }
- zk->last_ret = ZOK;
- zk->last_errno = 0;
- if (items > 2 && items % 2) {
- Perl_croak(aTHX_ "invalid number of arguments");
- }
- for (i = 2; i < items; i += 2) {
- char *key = SvPV_nolen(ST(i));
- if (strcaseEQ(key, "version")) {
- version = SvIV(ST(i + 1));
- if (version < 0) {
- Perl_croak(aTHX_ "invalid version requirement: %d",
- version);
- }
- }
- }
- errno = 0;
- ret = zoo_delete(zk->handle, path, version);
- zk->last_ret = ret;
- zk->last_errno = errno;
- if (ret == ZOK) {
- XSRETURN_YES;
- }
- else {
- XSRETURN_NO;
- }
- void
- zk_exists(zkh, path, ...)
- Net::ZooKeeper zkh
- char *path
- PREINIT:
- zk_t *zk;
- zk_stat_t *stat = NULL;
- zk_watch_t *old_watch = NULL;
- zk_handle_t *watch_handle = NULL;
- watcher_fn watcher = NULL;
- zk_watch_t *new_watch = NULL;
- int i, ret;
- PPCODE:
- zk = _zk_get_handle_outer(aTHX_ zkh);
- if (!zk) {
- Perl_croak(aTHX_ "invalid handle");
- }
- zk->last_ret = ZOK;
- zk->last_errno = 0;
- if (items > 2 && items % 2) {
- Perl_croak(aTHX_ "invalid number of arguments");
- }
- for (i = 2; i < items; i += 2) {
- char *key = SvPV_nolen(ST(i));
- if (strcaseEQ(key, "stat")) {
- if (!SvROK(ST(i + 1)) || SvTYPE(SvRV(ST(i + 1))) != SVt_PVHV ||
- !sv_derived_from(ST(i + 1), STAT_PACKAGE_NAME)) {
- Perl_croak(aTHX_ "stat is not a hash reference of "
- "type " STAT_PACKAGE_NAME);
- }
- stat = _zks_get_handle_outer(aTHX_ (HV*) SvRV(ST(i + 1)));
- if (!stat) {
- Perl_croak(aTHX_ "invalid stat handle");
- }
- }
- else if (strcaseEQ(key, "watch")) {
- if (!SvROK(ST(i + 1)) || SvTYPE(SvRV(ST(i + 1))) != SVt_PVHV ||
- !sv_derived_from(ST(i + 1), WATCH_PACKAGE_NAME)) {
- Perl_croak(aTHX_ "watch is not a hash reference of "
- "type " WATCH_PACKAGE_NAME);
- }
- old_watch = _zkw_get_handle_outer(aTHX_ (HV*) SvRV(ST(i + 1)),
- &watch_handle);
- if (!old_watch) {
- Perl_croak(aTHX_ "invalid watch handle");
- }
- }
- }
- if (watch_handle) {
- new_watch = _zk_acquire_watch(aTHX);
- if (!new_watch) {
- /* errno will be set */
- zk->last_ret = ZSYSTEMERROR;
- zk->last_errno = errno;
- XSRETURN_NO;
- }
- watcher = _zk_watcher;
- }
- errno = 0;
- ret = zoo_wexists(zk->handle, path, watcher, new_watch, stat);
- zk->last_ret = ret;
- zk->last_errno = errno;
- if (watch_handle) {
- _zk_replace_watch(aTHX_ watch_handle, zk->first_watch,
- old_watch, new_watch);
- }
- if (ret == ZOK) {
- XSRETURN_YES;
- }
- else {
- XSRETURN_NO;
- }
- void
- zk_get_children(zkh, path, ...)
- Net::ZooKeeper zkh
- char *path
- PREINIT:
- zk_t *zk;
- zk_watch_t *old_watch = NULL;
- zk_handle_t *watch_handle = NULL;
- watcher_fn watcher = NULL;
- zk_watch_t *new_watch = NULL;
- struct String_vector strings;
- int i, ret;
- PPCODE:
- zk = _zk_get_handle_outer(aTHX_ zkh);
- if (!zk) {
- Perl_croak(aTHX_ "invalid handle");
- }
- zk->last_ret = ZOK;
- zk->last_errno = 0;
- if (items > 2 && items % 2) {
- Perl_croak(aTHX_ "invalid number of arguments");
- }
- for (i = 2; i < items; i += 2) {
- char *key = SvPV_nolen(ST(i));
- if (strcaseEQ(key, "watch")) {
- if (!SvROK(ST(i + 1)) || SvTYPE(SvRV(ST(i + 1))) != SVt_PVHV ||
- !sv_derived_from(ST(i + 1), WATCH_PACKAGE_NAME)) {
- Perl_croak(aTHX_ "watch is not a hash reference of "
- "type " WATCH_PACKAGE_NAME);
- }
- old_watch = _zkw_get_handle_outer(aTHX_ (HV*) SvRV(ST(i + 1)),
- &watch_handle);
- if (!old_watch) {
- Perl_croak(aTHX_ "invalid watch handle");
- }
- }
- }
- if (watch_handle) {
- new_watch = _zk_acquire_watch(aTHX);
- if (!new_watch) {
- /* errno will be set */
- zk->last_ret = ZSYSTEMERROR;
- zk->last_errno = errno;
- if (GIMME_V == G_ARRAY) {
- XSRETURN_EMPTY;
- }
- else {
- XSRETURN_UNDEF;
- }
- }
- watcher = _zk_watcher;
- }
- Zero(&strings, 1, struct String_vector);
- errno = 0;
- ret = zoo_wget_children(zk->handle, path, watcher, new_watch,
- &strings);
- zk->last_ret = ret;
- zk->last_errno = errno;
- if (watch_handle) {
- _zk_replace_watch(aTHX_ watch_handle, zk->first_watch,
- old_watch, new_watch);
- }
- if (ret == ZOK) {
- int num_children;
- num_children =
- (strings.count > PERL_INT_MAX) ? PERL_INT_MAX : strings.count;
- if (GIMME_V == G_ARRAY && num_children > 0) {
- EXTEND(SP, num_children);
- for (i = 0; i < num_children; ++i) {
- ST(i) = sv_2mortal(newSVpv(strings.data[i], 0));
- }
- }
- /* NOTE: would be nice if this were documented as required */
- deallocate_String_vector(&strings);
- if (GIMME_V == G_ARRAY) {
- if (num_children == 0) {
- XSRETURN_EMPTY;
- }
- XSRETURN(num_children);
- }
- else {
- ST(0) = sv_2mortal(newSViv(num_children));
- XSRETURN(1);
- }
- }
- else {
- if (GIMME_V == G_ARRAY) {
- XSRETURN_EMPTY;
- }
- else {
- XSRETURN_UNDEF;
- }
- }
- void
- zk_get(zkh, path, ...)
- Net::ZooKeeper zkh
- char *path
- PREINIT:
- zk_t *zk;
- int buf_len;
- zk_stat_t *stat = NULL;
- zk_watch_t *old_watch = NULL;
- zk_handle_t *watch_handle = NULL;
- char *buf;
- watcher_fn watcher = NULL;
- zk_watch_t *new_watch = NULL;
- int i, ret;
- PPCODE:
- zk = _zk_get_handle_outer(aTHX_ zkh);
- if (!zk) {
- Perl_croak(aTHX_ "invalid handle");
- }
- zk->last_ret = ZOK;
- zk->last_errno = 0;
- if (items > 2 && items % 2) {
- Perl_croak(aTHX_ "invalid number of arguments");
- }
- buf_len = zk->data_buf_len;
- for (i = 2; i < items; i += 2) {
- char *key = SvPV_nolen(ST(i));
- if (strcaseEQ(key, "data_read_len")) {
- buf_len = SvIV(ST(i + 1));
- if (buf_len < 0) {
- Perl_croak(aTHX_ "invalid data read length: %d",
- buf_len);
- }
- }
- else if (strcaseEQ(key, "stat")) {
- if (!SvROK(ST(i + 1)) || SvTYPE(SvRV(ST(i + 1))) != SVt_PVHV ||
- !sv_derived_from(ST(i + 1), STAT_PACKAGE_NAME)) {
- Perl_croak(aTHX_ "stat is not a hash reference of "
- "type " STAT_PACKAGE_NAME);
- }
- stat = _zks_get_handle_outer(aTHX_ (HV*) SvRV(ST(i + 1)));
- if (!stat) {
- Perl_croak(aTHX_ "invalid stat handle");
- }
- }
- else if (strcaseEQ(key, "watch")) {
- if (!SvROK(ST(i + 1)) || SvTYPE(SvRV(ST(i + 1))) != SVt_PVHV ||
- !sv_derived_from(ST(i + 1), WATCH_PACKAGE_NAME)) {
- Perl_croak(aTHX_ "watch is not a hash reference of "
- "type " WATCH_PACKAGE_NAME);
- }
- old_watch = _zkw_get_handle_outer(aTHX_ (HV*) SvRV(ST(i + 1)),
- &watch_handle);
- if (!old_watch) {
- Perl_croak(aTHX_ "invalid watch handle");
- }
- }
- }
- if (watch_handle) {
- new_watch = _zk_acquire_watch(aTHX);
- if (!new_watch) {
- /* errno will be set */
- zk->last_ret = ZSYSTEMERROR;
- zk->last_errno = errno;
- XSRETURN_UNDEF;
- }
- watcher = _zk_watcher;
- }
- Newx(buf, buf_len + 1, char);
- errno = 0;
- ret = zoo_wget(zk->handle, path, watcher, new_watch,
- buf, &buf_len, stat);
- zk->last_ret = ret;
- zk->last_errno = errno;
- if (watch_handle) {
- _zk_replace_watch(aTHX_ watch_handle, zk->first_watch,
- old_watch, new_watch);
- }
- if (ret == ZOK && buf_len != -1) {
- ST(0) = sv_newmortal();
- #ifdef SV_HAS_TRAILING_NUL
- buf[buf_len] = '\0';
- sv_usepvn_flags(ST(0), buf, buf_len, SV_HAS_TRAILING_NUL);
- #else
- sv_usepvn(ST(0), buf, buf_len);
- #endif
- XSRETURN(1);
- }
- else {
- Safefree(buf);
- XSRETURN_UNDEF;
- }
- void
- zk_set(zkh, path, buf, ...)
- Net::ZooKeeper zkh
- char *path
- char *buf; buf = (char *) SvPV($arg, buf_len);
- PREINIT:
- zk_t *zk;
- int version = -1;
- zk_stat_t *stat = NULL;
- STRLEN buf_len;
- int i, ret;
- PPCODE:
- zk = _zk_get_handle_outer(aTHX_ zkh);
- if (!zk) {
- Perl_croak(aTHX_ "invalid handle");
- }
- zk->last_ret = ZOK;
- zk->last_errno = 0;
- if (items > 3 && !(items % 2)) {
- Perl_croak(aTHX_ "invalid number of arguments");
- }
- if (buf_len > PERL_INT_MAX) {
- Perl_croak(aTHX_ "invalid data length: %zu", buf_len);
- }
- for (i = 3; i < items; i += 2) {
- char *key = SvPV_nolen(ST(i));
- if (strcaseEQ(key, "version")) {
- version = SvIV(ST(i + 1));
- if (version < 0) {
- Perl_croak(aTHX_ "invalid version requirement: %d",
- version);
- }
- }
- else if (strcaseEQ(key, "stat")) {
- if (!SvROK(ST(i + 1)) || SvTYPE(SvRV(ST(i + 1))) != SVt_PVHV ||
- !sv_derived_from(ST(i + 1), STAT_PACKAGE_NAME)) {
- Perl_croak(aTHX_ "stat is not a hash reference of "
- "type " STAT_PACKAGE_NAME);
- }
- stat = _zks_get_handle_outer(aTHX_ (HV*) SvRV(ST(i + 1)));
- if (!stat) {
- Perl_croak(aTHX_ "invalid stat handle");
- }
- }
- }
- errno = 0;
- ret = zoo_set2(zk->handle, path, buf, buf_len, version, stat);
- zk->last_ret = ret;
- zk->last_errno = errno;
- if (ret == ZOK) {
- XSRETURN_YES;
- }
- else {
- XSRETURN_NO;
- }
- void
- zk_get_acl(zkh, path, ...)
- Net::ZooKeeper zkh
- char *path
- PREINIT:
- zk_t *zk;
- zk_stat_t *stat = NULL;
- struct ACL_vector acl;
- int i, ret;
- PPCODE:
- zk = _zk_get_handle_outer(aTHX_ zkh);
- if (!zk) {
- Perl_croak(aTHX_ "invalid handle");
- }
- zk->last_ret = ZOK;
- zk->last_errno = 0;
- if (items > 2 && items % 2) {
- Perl_croak(aTHX_ "invalid number of arguments");
- }
- for (i = 2; i < items; i += 2) {
- char *key = SvPV_nolen(ST(i));
- if (strcaseEQ(key, "stat")) {
- if (!SvROK(ST(i + 1)) || SvTYPE(SvRV(ST(i + 1))) != SVt_PVHV ||
- !sv_derived_from(ST(i + 1), STAT_PACKAGE_NAME)) {
- Perl_croak(aTHX_ "stat is not a hash reference of "
- "type " STAT_PACKAGE_NAME);
- }
- stat = _zks_get_handle_outer(aTHX_ (HV*) SvRV(ST(i + 1)));
- if (!stat) {
- Perl_croak(aTHX_ "invalid stat handle");
- }
- }
- }
- errno = 0;
- ret = zoo_get_acl(zk->handle, path, &acl, stat);
- zk->last_ret = ret;
- zk->last_errno = errno;
- if (ret == ZOK) {
- int num_acl_entries;
- num_acl_entries =
- (acl.count > PERL_INT_MAX) ? PERL_INT_MAX : acl.count;
- if (GIMME_V == G_ARRAY && num_acl_entries > 0) {
- EXTEND(SP, num_acl_entries);
- for (i = 0; i < num_acl_entries; ++i) {
- HV *acl_entry_hash = newHV();
- _zk_fill_acl_entry_hash(aTHX_ &acl.data[i],
- acl_entry_hash);
- ST(i) = sv_2mortal(newRV_noinc((SV*) acl_entry_hash));
- }
- }
- /* NOTE: would be nice if this were documented as required */
- deallocate_ACL_vector(&acl);
- if (GIMME_V == G_ARRAY) {
- if (num_acl_entries == 0) {
- XSRETURN_EMPTY;
- }
- XSRETURN(num_acl_entries);
- }
- else {
- ST(0) = sv_2mortal(newSViv(num_acl_entries));
- XSRETURN(1);
- }
- }
- else {
- if (GIMME_V == G_ARRAY) {
- XSRETURN_EMPTY;
- }
- else {
- XSRETURN_UNDEF;
- }
- }
- void
- zk_set_acl(zkh, path, acl_arr, ...)
- Net::ZooKeeper zkh
- char *path
- AV *acl_arr
- PREINIT:
- zk_t *zk;
- const char *err;
- int version = -1;
- struct ACL_vector acl;
- int i, ret;
- PPCODE:
- zk = _zk_get_handle_outer(aTHX_ zkh);
- if (!zk) {
- Perl_croak(aTHX_ "invalid handle");
- }
- zk->last_ret = ZOK;
- zk->last_errno = 0;
- if (items > 3 && !(items % 2)) {
- Perl_croak(aTHX_ "invalid number of arguments");
- }
- err = _zk_fill_acl(aTHX_ acl_arr, &acl);
- if (err) {
- Perl_croak(aTHX_ "%s", err);
- }
- for (i = 3; i < items; i += 2) {
- char *key = SvPV_nolen(ST(i));
- if (strcaseEQ(key, "version")) {
- version = SvIV(ST(i + 1));
- if (version < 0) {
- Perl_croak(aTHX_ "invalid version requirement: %d",
- version);
- }
- }
- }
- errno = 0;
- ret = zoo_set_acl(zk->handle, path, version, &acl);
- zk->last_ret = ret;
- zk->last_errno = errno;
- _zk_free_acl(aTHX_ &acl);
- if (ret == ZOK) {
- XSRETURN_YES;
- }
- else {
- XSRETURN_NO;
- }
- void
- zk_stat(zkh)
- Net::ZooKeeper zkh
- PREINIT:
- zk_t *zk;
- zk_handle_t *handle;
- HV *stash, *stat_hash, *attr_hash;
- SV *attr;
- PPCODE:
- zk = _zk_get_handle_outer(aTHX_ zkh);
- if (!zk) {
- Perl_croak(aTHX_ "invalid handle");
- }
- zk->last_ret = ZOK;
- zk->last_errno = 0;
- Newx(handle, 1, zk_handle_t);
- handle->signature = STAT_PACKAGE_SIGNATURE;
- Newxz(handle->handle.stat, 1, zk_stat_t);
- /* As in zk_new(), we use two levels of magic here. */
- stash = gv_stashpv(STAT_PACKAGE_NAME, GV_ADDWARN);
- attr_hash = newHV();
- sv_magic((SV*) attr_hash, Nullsv, PERL_MAGIC_ext,
- (const char*) handle, 0);
- attr = sv_bless(newRV_noinc((SV*) attr_hash), stash);
- stat_hash = newHV();
- sv_magic((SV*) stat_hash, attr, PERL_MAGIC_tied, Nullch, 0);
- SvREFCNT_dec(attr);
- ST(0) = sv_bless(sv_2mortal(newRV_noinc((SV*) stat_hash)), stash);
- XSRETURN(1);
- void
- zk_watch(zkh, ...)
- Net::ZooKeeper zkh
- PREINIT:
- zk_t *zk;
- unsigned int timeout;
- zk_watch_t *watch;
- zk_handle_t *handle;
- HV *stash, *watch_hash, *attr_hash;
- SV *attr;
- int i;
- PPCODE:
- zk = _zk_get_handle_outer(aTHX_ zkh);
- if (!zk) {
- Perl_croak(aTHX_ "invalid handle");
- }
- zk->last_ret = ZOK;
- zk->last_errno = 0;
- if (items > 1 && !(items % 2)) {
- Perl_croak(aTHX_ "invalid number of arguments");
- }
- timeout = zk->watch_timeout;
- for (i = 1; i < items; i += 2) {
- char *key = SvPV_nolen(ST(i));
- if (strcaseEQ(key, "timeout")) {
- timeout = SvUV(ST(i + 1));
- }
- }
- watch = _zk_acquire_watch(aTHX);
- if (!watch) {
- /* errno will be set */
- zk->last_ret = ZSYSTEMERROR;
- zk->last_errno = errno;
- XSRETURN_UNDEF;
- }
- Newx(handle, 1, zk_handle_t);
- handle->signature = WATCH_PACKAGE_SIGNATURE;
- handle->handle.watch = watch;
- /* As in zk_new(), we use two levels of magic here. */
- stash = gv_stashpv(WATCH_PACKAGE_NAME, GV_ADDWARN);
- attr_hash = newHV();
- watch->timeout = timeout;
- sv_magic((SV*) attr_hash, Nullsv, PERL_MAGIC_ext,
- (const char*) handle, 0);
- attr = sv_bless(newRV_noinc((SV*) attr_hash), stash);
- watch_hash = newHV();
- sv_magic((SV*) watch_hash, attr, PERL_MAGIC_tied, Nullch, 0);
- SvREFCNT_dec(attr);
- ST(0) = sv_bless(sv_2mortal(newRV_noinc((SV*) watch_hash)), stash);
- XSRETURN(1);
- MODULE = Net::ZooKeeper PACKAGE = Net::ZooKeeper::Stat PREFIX = zks_
- void
- zks_DESTROY(zksh)
- Net::ZooKeeper::Stat zksh
- PREINIT:
- zk_handle_t *handle;
- HV *attr_hash;
- int ret = ZBADARGUMENTS;
- PPCODE:
- handle = _zk_check_handle_outer(aTHX_ zksh, &attr_hash,
- STAT_PACKAGE_NAME,
- STAT_PACKAGE_SIGNATURE);
- if (!handle) {
- handle = _zk_check_handle_inner(aTHX_ zksh,
- STAT_PACKAGE_SIGNATURE);
- if (handle) {
- attr_hash = zksh;
- zksh = NULL;
- }
- }
- if (handle) {
- ret = ZOK;
- Safefree(handle->handle.stat);
- Safefree(handle);
- sv_unmagic((SV*) attr_hash, PERL_MAGIC_ext);
- }
- if (zksh && attr_hash) {
- sv_unmagic((SV*) zksh, PERL_MAGIC_tied);
- }
- if (GIMME_V == G_VOID) {
- XSRETURN_EMPTY;
- }
- else if (ret == ZOK) {
- XSRETURN_YES;
- }
- else {
- XSRETURN_NO;
- }
- void
- zks_CLONE(package)
- char *package
- PPCODE:
- XSRETURN_EMPTY;
- void
- zks_CLONE_SKIP(package)
- char *package
- PPCODE:
- XSRETURN_YES;
- void
- zks_TIEHASH(package, ...)
- char *package
- PPCODE:
- Perl_croak(aTHX_ "tying hashes of class "
- STAT_PACKAGE_NAME " not supported");
- void
- zks_UNTIE(attr_hash, ref_count)
- Net::ZooKeeper::Stat attr_hash
- IV ref_count
- PPCODE:
- Perl_croak(aTHX_ "untying hashes of class "
- STAT_PACKAGE_NAME " not supported");
- void
- zks_FIRSTKEY(attr_hash)
- Net::ZooKeeper::Stat attr_hash
- PREINIT:
- zk_stat_t *stat;
- PPCODE:
- stat = _zks_get_handle_inner(aTHX_ attr_hash);
- if (!stat) {
- Perl_croak(aTHX_ "invalid handle");
- }
- ST(0) = sv_2mortal(newSVpvn(zk_stat_keys[0].name,
- zk_stat_keys[0].name_len));
- XSRETURN(1);
- void
- zks_NEXTKEY(attr_hash, attr_key)
- Net::ZooKeeper::Stat attr_hash
- SV *attr_key
- PREINIT:
- zk_stat_t *stat;
- char *key;
- int i;
- PPCODE:
- stat = _zks_get_handle_inner(aTHX_ attr_hash);
- if (!stat) {
- Perl_croak(aTHX_ "invalid handle");
- }
- key = SvPV_nolen(attr_key);
- for (i = 0; i < NUM_STAT_KEYS; ++i) {
- if (strcaseEQ(key, zk_stat_keys[i].name)) {
- ++i;
- break;
- }
- }
- if (i < NUM_STAT_KEYS) {
- ST(0) = sv_2mortal(newSVpvn(zk_stat_keys[i].name,
- zk_stat_keys[i].name_len));
- XSRETURN(1);
- }
- else {
- XSRETURN_EMPTY;
- }
- void
- zks_SCALAR(attr_hash)
- Net::ZooKeeper::Stat attr_hash
- PPCODE:
- XSRETURN_YES;
- void
- zks_FETCH(attr_hash, attr_key)
- Net::ZooKeeper::Stat attr_hash
- SV *attr_key
- PREINIT:
- zk_stat_t *stat;
- char *key;
- SV *val = NULL;
- int i;
- PPCODE:
- stat = _zks_get_handle_inner(aTHX_ attr_hash);
- if (!stat) {
- Perl_croak(aTHX_ "invalid handle");
- }
- key = SvPV_nolen(attr_key);
- for (i = 0; i < NUM_STAT_KEYS; ++i) {
- if (strcaseEQ(key, zk_stat_keys[i].name)) {
- if (zk_stat_keys[i].size * CHAR_BIT == 32) {
- val = newSViv(*((int32_t*) (((char*) stat) +
- zk_stat_keys[i].offset)));
- }
- else {
- /* NOTE: %lld is inconsistent, so cast to a double */
- val = newSVpvf("%.0f", (double)
- *((int64_t*) (((char*) stat) +
- zk_stat_keys[i].offset)));
- }
- break;
- }
- }
- if (val) {
- ST(0) = sv_2mortal(val);
- XSRETURN(1);
- }
- Perl_warn(aTHX_ "invalid element: %s", key);
- XSRETURN_UNDEF;
- void
- zks_STORE(attr_hash, attr_key, attr_val)
- Net::ZooKeeper::Stat attr_hash
- SV *attr_key
- SV *attr_val
- PREINIT:
- zk_stat_t *stat;
- char *key;
- int i;
- PPCODE:
- stat = _zks_get_handle_inner(aTHX_ attr_hash);
- if (!stat) {
- Perl_croak(aTHX_ "invalid handle");
- }
- key = SvPV_nolen(attr_key);
- for (i = 0; i < NUM_STAT_KEYS; ++i) {
- if (strcaseEQ(key, zk_stat_keys[i].name)) {
- Perl_warn(aTHX_ "read-only element: %s", key);
- XSRETURN_EMPTY;
- }
- }
- Perl_warn(aTHX_ "invalid element: %s", key);
- XSRETURN_EMPTY;
- void
- zks_EXISTS(attr_hash, attr_key)
- Net::ZooKeeper::Stat attr_hash
- SV *attr_key
- PREINIT:
- zk_stat_t *stat;
- char *key;
- int i;
- PPCODE:
- stat = _zks_get_handle_inner(aTHX_ attr_hash);
- if (!stat) {
- Perl_croak(aTHX_ "invalid handle");
- }
- key = SvPV_nolen(attr_key);
- for (i = 0; i < NUM_STAT_KEYS; ++i) {
- if (strcaseEQ(key, zk_stat_keys[i].name)) {
- XSRETURN_YES;
- }
- }
- XSRETURN_NO;
- void
- zks_DELETE(attr_hash, attr_key)
- Net::ZooKeeper::Stat attr_hash
- SV *attr_key
- PPCODE:
- Perl_warn(aTHX_ "deleting elements from hashes of class "
- STAT_PACKAGE_NAME " not supported");
- XSRETURN_EMPTY;
- void
- zks_CLEAR(attr_hash)
- Net::ZooKeeper::Stat attr_hash
- PPCODE:
- Perl_warn(aTHX_ "clearing hashes of class "
- STAT_PACKAGE_NAME " not supported");
- XSRETURN_EMPTY;
- MODULE = Net::ZooKeeper PACKAGE = Net::ZooKeeper::Watch PREFIX = zkw_
- void
- zkw_DESTROY(zkwh)
- Net::ZooKeeper::Watch zkwh
- PREINIT:
- zk_handle_t *handle;
- HV *attr_hash;
- int ret = ZBADARGUMENTS;
- PPCODE:
- handle = _zk_check_handle_outer(aTHX_ zkwh, &attr_hash,
- WATCH_PACKAGE_NAME,
- WATCH_PACKAGE_SIGNATURE);
- if (!handle) {
- handle = _zk_check_handle_inner(aTHX_ zkwh,
- WATCH_PACKAGE_SIGNATURE);
- if (handle) {
- attr_hash = zkwh;
- zkwh = NULL;
- }
- }
- if (handle) {
- ret = ZOK;
- _zk_release_watch(aTHX_ handle->handle.watch, 0);
- Safefree(handle);
- sv_unmagic((SV*) attr_hash, PERL_MAGIC_ext);
- }
- if (zkwh && attr_hash) {
- sv_unmagic((SV*) zkwh, PERL_MAGIC_tied);
- }
- if (GIMME_V == G_VOID) {
- XSRETURN_EMPTY;
- }
- else if (ret == ZOK) {
- XSRETURN_YES;
- }
- else {
- XSRETURN_NO;
- }
- void
- zkw_CLONE(package)
- char *package
- PPCODE:
- XSRETURN_EMPTY;
- void
- zkw_CLONE_SKIP(package)
- char *package
- PPCODE:
- XSRETURN_YES;
- void
- zkw_TIEHASH(package, ...)
- char *package
- PPCODE:
- Perl_croak(aTHX_ "tying hashes of class "
- WATCH_PACKAGE_NAME " not supported");
- void
- zkw_UNTIE(attr_hash, ref_count)
- Net::ZooKeeper::Watch attr_hash
- IV ref_count
- PPCODE:
- Perl_croak(aTHX_ "untying hashes of class "
- WATCH_PACKAGE_NAME " not supported");
- void
- zkw_FIRSTKEY(attr_hash)
- Net::ZooKeeper::Watch attr_hash
- PREINIT:
- zk_watch_t *watch;
- PPCODE:
- watch = _zkw_get_handle_inner(aTHX_ attr_hash);
- if (!watch) {
- Perl_croak(aTHX_ "invalid handle");
- }
- ST(0) = sv_2mortal(newSVpvn(zk_watch_keys[0].name,
- zk_watch_keys[0].name_len));
- XSRETURN(1);
- void
- zkw_NEXTKEY(attr_hash, attr_key)
- Net::ZooKeeper::Watch attr_hash
- SV *attr_key
- PREINIT:
- zk_watch_t *watch;
- char *key;
- int i;
- PPCODE:
- watch = _zkw_get_handle_inner(aTHX_ attr_hash);
- if (!watch) {
- Perl_croak(aTHX_ "invalid handle");
- }
- key = SvPV_nolen(attr_key);
- for (i = 0; i < NUM_WATCH_KEYS; ++i) {
- if (strcaseEQ(key, zk_watch_keys[i].name)) {
- ++i;
- break;
- }
- }
- if (i < NUM_WATCH_KEYS) {
- ST(0) = sv_2mortal(newSVpvn(zk_watch_keys[i].name,
- zk_watch_keys[i].name_len));
- XSRETURN(1);
- }
- else {
- XSRETURN_EMPTY;
- }
- void
- zkw_SCALAR(attr_hash)
- Net::ZooKeeper::Watch attr_hash
- PPCODE:
- XSRETURN_YES;
- void
- zkw_FETCH(attr_hash, attr_key)
- Net::ZooKeeper::Watch attr_hash
- SV *attr_key
- PREINIT:
- zk_watch_t *watch;
- char *key;
- SV *val = NULL;
- PPCODE:
- watch = _zkw_get_handle_inner(aTHX_ attr_hash);
- if (!watch) {
- Perl_croak(aTHX_ "invalid handle");
- }
- key = SvPV_nolen(attr_key);
- if (strcaseEQ(key, "timeout")) {
- val = newSVuv(watch->timeout);
- }
- else if (strcaseEQ(key, "event")) {
- val = newSViv(watch->event_type);
- }
- else if (strcaseEQ(key, "state")) {
- val = newSViv(watch->event_state);
- }
- if (val) {
- ST(0) = sv_2mortal(val);
- XSRETURN(1);
- }
- Perl_warn(aTHX_ "invalid element: %s", key);
- XSRETURN_UNDEF;
- void
- zkw_STORE(attr_hash, attr_key, attr_val)
- Net::ZooKeeper::Watch attr_hash
- SV *attr_key
- SV *attr_val
- PREINIT:
- zk_watch_t *watch;
- char *key;
- PPCODE:
- watch = _zkw_get_handle_inner(aTHX_ attr_hash);
- if (!watch) {
- Perl_croak(aTHX_ "invalid handle");
- }
- key = SvPV_nolen(attr_key);
- if (strcaseEQ(key, "timeout")) {
- watch->timeout = SvUV(attr_val);
- }
- else {
- int i;
- for (i = 0; i < NUM_WATCH_KEYS; ++i) {
- if (strcaseEQ(key, zk_watch_keys[i].name)) {
- Perl_warn(aTHX_ "read-only element: %s", key);
- XSRETURN_EMPTY;
- }
- }
- Perl_warn(aTHX_ "invalid element: %s", key);
- }
- XSRETURN_EMPTY;
- void
- zkw_EXISTS(attr_hash, attr_key)
- Net::ZooKeeper::Watch attr_hash
- SV *attr_key
- PREINIT:
- zk_watch_t *watch;
- char *key;
- int i;
- PPCODE:
- watch = _zkw_get_handle_inner(aTHX_ attr_hash);
- if (!watch) {
- Perl_croak(aTHX_ "invalid handle");
- }
- key = SvPV_nolen(attr_key);
- for (i = 0; i < NUM_WATCH_KEYS; ++i) {
- if (strcaseEQ(key, zk_watch_keys[i].name)) {
- XSRETURN_YES;
- }
- }
- XSRETURN_NO;
- void
- zkw_DELETE(attr_hash, attr_key)
- Net::ZooKeeper::Watch attr_hash
- SV *attr_key
- PPCODE:
- Perl_warn(aTHX_ "deleting elements from hashes of class "
- WATCH_PACKAGE_NAME " not supported");
- XSRETURN_EMPTY;
- void
- zkw_CLEAR(attr_hash)
- Net::ZooKeeper::Watch attr_hash
- PPCODE:
- Perl_warn(aTHX_ "clearing hashes of class "
- WATCH_PACKAGE_NAME " not supported");
- XSRETURN_EMPTY;
- void
- zkw_wait(zkwh, ...)
- Net::ZooKeeper::Watch zkwh
- PREINIT:
- zk_watch_t *watch;
- unsigned int timeout;
- struct timeval end_timeval;
- int i, done;
- struct timespec wait_timespec;
- PPCODE:
- watch = _zkw_get_handle_outer(aTHX_ zkwh, NULL);
- if (!watch) {
- Perl_croak(aTHX_ "invalid handle");
- }
- if (items > 1 && !(items % 2)) {
- Perl_croak(aTHX_ "invalid number of arguments");
- }
- timeout = watch->timeout;
- for (i = 1; i < items; i += 2) {
- char *key = SvPV_nolen(ST(i));
- if (strcaseEQ(key, "timeout")) {
- timeout = SvUV(ST(i + 1));
- }
- }
- gettimeofday(&end_timeval, NULL);
- end_timeval.tv_sec += timeout / 1000;
- end_timeval.tv_usec += (timeout % 1000) * 1000;
- wait_timespec.tv_sec = end_timeval.tv_sec;
- wait_timespec.tv_nsec = end_timeval.tv_usec * 1000;
- pthread_mutex_lock(&watch->mutex);
- while (!watch->done) {
- struct timeval curr_timeval;
- gettimeofday(&curr_timeval, NULL);
- if (end_timeval.tv_sec < curr_timeval.tv_sec ||
- (end_timeval.tv_sec == curr_timeval.tv_sec &&
- end_timeval.tv_usec <= curr_timeval.tv_usec)) {
- break;
- }
- pthread_cond_timedwait(&watch->cond, &watch->mutex,
- &wait_timespec);
- }
- done = watch->done;
- pthread_mutex_unlock(&watch->mutex);
- if (done) {
- XSRETURN_YES;
- }
- else {
- XSRETURN_NO;
- }
|