On Fri, 1 Feb 2019 10:57:00 -0500 Andrew Piskorski <a...@piskorski.com> wrote:
> What if you don't care much about Tcl objects? A C pointer is already > easily shareable across threads (you just need the proper mutex > locking when using it), the trick is finding it again using some > handle from Tcl. For simplicity, should I just completely ignore the > whole Tcl_Obj machinery when doing that? Of course. You can always use a lock, hash-table and key your pointers, passing the key to the Tcl. But you asked for some other way to do it :-) > > Or SHOULD I (always?) make my handle into a Tcl_Obj? If so, can you > go into a bit more detail on WHY that's a better approach? Even > despite the fact that this Tcl_Obj thing is now more difficult to > share across threads? By having a Tcl object that contains ptr rep, you can safely toss it arround Tcl as it will be a "natural" Tcl thing. You can treat it everywhere as a regular Tcl object. Whereas if you opt for the above approach, you need to "know" what that key points to. If you are only consumer of that key it is pretty OK to do it. But if you are passing ptr's arround the "unknown" code you might be better with object. This is why we did the ns:addr object, so that we do not have to care. It is really the same thing but other way around. > > If I take an ordinary sort of Tcl string or integer and hand it to my > C code, that works fine as the key for an nsv or Tcl_HashTable lookup. > Of course, the code doesn't "know" that that particular string is > supposed to be a handle, but there's nothing stopping me from simply > using it as one in the C code, and throwing an error if I can't find a > hash entry for it. Exactly. > > I suspect that the above is NOT the recommended approach, but I don't > fully understand why. It seems "simpler" to me... But maybe that's > only because I don't yet understand the Tcl_Obj integration approach, > and what benefits it provides. It is "simpler" because you are used to it. But in essence, you need to make a shared hash table, invent a key for your pointers and make sure all is always properly locked. So it isn't per-se simpler. It is still a devil, but that devil isn't that black because you already know it :-) OTOH, if you use ns:addr object, you need not take care about locking and all the other trivia at all. It is the "rest" of the system that needs to do that. > Hm, that has Ns_TclSetTwoPtrValue(), Ns_TclGetOpaqueFromObj(), and > other black magic (or so it seems to me). Are there docs on these C > APIs anywhere? No. But it is really trivial. If you want to wrap a ptr into the ns:addr object you can do: Tcl_Obj *myObj = Tcl_NewObj(); char *myType = "at-ptr"; /* Name it as you want */ MyDataStruct *myStruct = &MyGlobalStruct; Ns_TclSetAddrObj(myObj, myType, (void*)myStruct); Now you can pass the myObj to Tcl (put it in result, bury it in some list, store it in nsv array etc.pp.). Your code may later access the address/ptr value: Tcl_Obj *myObj = objv[1]; /* For example */ MyDataStruct *myStruct; Ns_TclGetOpaqueFromObj(myObj, myType, (void**)&myStruct); so now you have (or don't if GetOpaque retuns TCL_ERROR) your initial *myStruct value. > > Some of the stuff in "nsd/tclobj.c" seems be primarily concerned with > the "address object type" (IP addresses?), but I get the sense that > much of that code is much more general purpose than that. I see that > "nsd/tcltime.c" uses the tclobj.c functions to implement an Ns_Time > Tcl_Obj type, but I definitely don't understand how or why yet! > It's (memory-)addresses == pointers. HTH, Zoran _______________________________________________ naviserver-devel mailing list naviserver-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/naviserver-devel