diff --git a/lib/modules/Remote.pmod/call.pike b/lib/modules/Remote.pmod/call.pike index 8274c96f58caae3a03e1c31bf43b504ae2666bd8..ac44c70cf067b6a2b9f5179aa672bae2b36bb4d0 100644 --- a/lib/modules/Remote.pmod/call.pike +++ b/lib/modules/Remote.pmod/call.pike @@ -13,7 +13,8 @@ int _async; mixed `() (mixed ... args) { - mixed data = ctx->encode_call(objectid, name, args, _async); + mixed data = ctx->encode_call(objectid, name, args, + _async ? CTX_CALL_ASYNC : CTX_CALL_SYNC); if (_async) con->call_async(data); else @@ -23,16 +24,22 @@ mixed `() (mixed ... args) mixed sync(mixed ... args) { - mixed data = ctx->encode_call(objectid, name, args, _async); + mixed data = ctx->encode_call(objectid, name, args, CTX_CALL_SYNC); return con->call_sync(data); } void async(mixed ... args) { - mixed data = ctx->encode_call(objectid, name, args, 1); + mixed data = ctx->encode_call(objectid, name, args, CTX_CALL_ASYNC); con->call_async(data); } +int exists() +{ + mixed data = ctx->encode_call(objectid, name, ({}), CTX_EXISTS); + return con->call_sync(data); +} + int is_async() { return _async; diff --git a/lib/modules/Remote.pmod/connection.pike b/lib/modules/Remote.pmod/connection.pike index 1f13aefa66dbef112f941cf1ef78253830586a1d..acf68c0219018b5d2fdc7704a52b0d0df7c1f0b7 100644 --- a/lib/modules/Remote.pmod/connection.pike +++ b/lib/modules/Remote.pmod/connection.pike @@ -165,7 +165,8 @@ void try_close() closed = -1; catch { // This should work with most older Remote implementations. - string s = encode_value(ctx->encode_call (0, "sOmE nOnSeNsE..", ({}), 0)); + string s = encode_value(ctx->encode_call (0, "sOmE nOnSeNsE..", ({}), + CTX_CALL_SYNC)); con->write (sprintf("%4c%s", sizeof(s), s)); }; #endif @@ -405,6 +406,10 @@ void read_some(int ignore, string s) } break; + case CTX_EXISTS: + return_value (data[4], ctx->decode_existp (data)); + break; + default: error("Unknown message"); } @@ -454,10 +459,14 @@ void read_thread() void server_read_thread() { - DEBUGMSG("server_read_thread\n"); - handshake (0, con->read (24, 1)); - read_thread(); + mixed err = catch { + DEBUGMSG("server_read_thread\n"); + handshake (0, con->read (24, 1)); + read_thread(); + }; + con = 0; DEBUGMSG("server_read_thread exit\n"); + if (err) throw (err); } void call_thread() diff --git a/lib/modules/Remote.pmod/context.pike b/lib/modules/Remote.pmod/context.pike index c609d2ced05fdaf6eb27962717ab93dea45f1571..b938c5edd5f7edee5a05524560be2eee33f90d39 100644 --- a/lib/modules/Remote.pmod/context.pike +++ b/lib/modules/Remote.pmod/context.pike @@ -153,20 +153,20 @@ mixed decode(array a) } } -array encode_call(object|string o, string|function f, array args, int async) +array encode_call(object|string o, string|function f, array args, int type) { - int type = (async ? CTX_CALL_ASYNC : CTX_CALL_SYNC); if(objectp(o)) - if(stringp(f)) + if(stringp(f) || !f) return ({ type, encode(o), f, encode(args), counter++ }); else - error("If the first argument is an object, the second must be a string"); + error("If the first argument is an object, " + "the second must be a string or zero"); else if(stringp(o)) - if(stringp(f)) + if(stringp(f) || !f) return ({ type, ({ CTX_OBJECT, o }), f, encode(args), counter++ }); else error("If the first argument is an object reference, " - "the second must be a string"); + "the second must be a string or zero"); else if(o) error("Error in arguments"); else if(functionp(f)||programp(f)) @@ -176,7 +176,7 @@ array encode_call(object|string o, string|function f, array args, int async) error("Error in arguments"); } -function decode_call(array data) +function|object decode_call(array data) { if((data[0] != CTX_CALL_SYNC) && (data[0] != CTX_CALL_ASYNC)) error("This is not a call"); @@ -194,7 +194,10 @@ function decode_call(array data) #ifdef REMOTE_DEBUG if (!o) DEBUGMSG(id + " not found\n"); #endif - return o && o[data[2]]; + if (data[2]) + return o && o[data[2]]; + else + return o; } else { string id = data[2][1]; @@ -206,6 +209,36 @@ function decode_call(array data) } } +int decode_existp(array data) +{ + if(data[0] != CTX_EXISTS) + error("This is not an exists check"); + if(data[1]) + { + string id = data[1][1]; + object o = id2val[id]; + if (o) + DEBUGMSG(id + " found locally\n"); + else if(!o && server_context && (o=server_context->object_for(id, con))) { + DEBUGMSG(id + " found in server_context\n"); + val2id[o] = id; + id2val[id] = o; + } +#ifdef REMOTE_DEBUG + if (!o) DEBUGMSG(id + " not found\n"); +#endif + return !!o; + } + else { + string id = data[2][1]; + object o = id2val[id]; +#ifdef REMOTE_DEBUG + if (!o) DEBUGMSG(id + " not found\n"); +#endif + return !!o; + } +} + void add(object o, string id) { DEBUGMSG(id + " added locally\n"); @@ -238,6 +271,9 @@ string describe(array data) return "<mapping "+sizeof(indices(data[1]))+">"; case CTX_ARRAY: return "<array "+sizeof(data[1])+">"; + case CTX_EXISTS: + return "exists["+(data[1] ? data[1][1]+"->"+data[2] : + "<function "+data[2][1]+">")+"]"; } return "<unknown "+data[0]+">"; } diff --git a/lib/modules/Remote.pmod/obj.pike b/lib/modules/Remote.pmod/obj.pike index d19cc23e4640ffb912d55a4af3cffe5c9f76a4cf..44f2d2f2930f1cd0b70d58b167e7a23cd86540c0 100644 --- a/lib/modules/Remote.pmod/obj.pike +++ b/lib/modules/Remote.pmod/obj.pike @@ -29,6 +29,12 @@ mixed `-> (string f) return get_function(f); } +int exists() +{ + mixed data = ctx->encode_call(id, 0, ({}), CTX_EXISTS); + return con->call_sync(data); +} + void create(string i, object cn, object ct) { id = i; diff --git a/lib/modules/Remote.pmod/remote.h b/lib/modules/Remote.pmod/remote.h index f04d4d5859726af8368948d12be6be02fdebfb24..7b29b70f92d650783b398173bbf8858526ea7750 100644 --- a/lib/modules/Remote.pmod/remote.h +++ b/lib/modules/Remote.pmod/remote.h @@ -27,3 +27,5 @@ program Obj = ((program)"obj"); #define CTX_RETURN 6 #define CTX_MAPPING 7 #define CTX_CALL_ASYNC 8 +#define CTX_EXISTS 9 +#define CTX_EXIST_RES 10