Wednesday, May 11, 2016

primitive_and_prototype_chain

var i = 10
Object.prototype.foo = 'Foo';
alert( i.foo ) //Foo

i.bar = 'Bar' // No effect: primitive is not extensive in own props
alert( i.bar )// undefined

alert( i.constructor ) // function Number(){}
alert( typeof i.constructor.prototype ) //object

Sunday, May 8, 2016

reference

var myObject = {};
var copyOfMyObject = myObject;
myObject.foo = 'bar';
console.log(myObject, copyOfMyObject); // logs 'Object { foo="bar"} Object { foo="bar"}'

=== operator for js

var price1 = 10;
var price2 = 10;
var price3 = new Number('10');
var price4 = price3;
var price5 = new Number('10');
console.log(price1 === price2); // logs true: primitive values compared by value

console.log(price1 === price3); //logs false: compares object with primitive

console.log(price4 === price3);// logs true: same references

alert("now checking price5...")
console.log(price5 === price3);// logs false: diff references

Monday, January 18, 2016

single-threaded apartment

/*Rules for single-threaded apartments are simple, but it is important to follow them carefully: Every object should live on only one thread (within a single-threaded apartment). Marshal all pointers to objects when passing them between apartments./*传统线程可以访问同进程内的资源*/ Each single-threaded apartment must have a message loop to handle calls from other processes and apartments within the same process. Single-threaded apartments without objects (client only) also need a message loop to dispatch broadcast sendmessages that some applications use. DLL-based or in-process objects do not call the COM initialization ;Each thread of a client process or out-of-process server must call CoInitialize, or call CoInitializeEx and specify COINIT_APARTMENTTHREADED for the dwCoInit parameter。The main apartment is the thread that calls CoInitializeEx first. DLL-based or in-process objects register their threading model with the ThreadingModel named-value under the InprocServer32 key in the registry. Apartment-aware objects must also write DLL entry points carefully. */ COM creates a hidden window using the Windows class "OleMainThreadWndClass" in each single-threaded apartment. A call to an object is received as a window message to this hidden window. When the object's apartment retrieves and dispatches the message, the hidden window will receive it. The window procedure will then call the corresponding interface method of the object. Single-threaded apartments can implement IMessageFilter 。 综上,单线程套间本质上是一个类(接口),保存着一个窗口句柄、一个线程(线程先初始化com库[就是注册],然后有消息loop)、0或多个组件对象、客户线程(也需要在com注册),该类(接口)可以进一步实施IMessageFilter接口。

In-Process Server Threading Issues

Like other servers, in-process servers can be single-threaded, apartment-threaded, or free-threaded. These servers can be used by any OLE client, regardless of the threading model used by that client. For an in-process server, when the threading model of the client and in-process server differ, COM must interpose itself between the client and the object. When an in-process object that supports the single-threaded model is called simultaneously by multiple threads of a client, COM cannot allow the client threads to directly access the object's interface—the object was not designed for such access.Instead, COM must ensure that calls are synchronized and are made only by the client thread that created the object. Therefore, COM creates the object in the client's main apartment and requires all the other client apartments to access the object by using proxies. When a free-threaded apartment (multithreaded apartment model) in a client creates an apartment-threaded in-process server, COM spins up a single-threaded apartment model "host" thread in the client. This host thread will create the object, and the interface pointer will be marshaled back to the client's free-threaded apartment. Similarly, when a single-threaded apartment in an apartment-model client creates a free-threaded in-process server, COM spins up a free-threaded host thread (multithreaded apartment on which the object will be created and then marshaled back to the client single-threaded apartment). COM helps protect access to objects provided by a single-threaded DLL by requiring access from the same client apartment in which they were created. In addition, all of the DLL entry points (like DllGetClassObject and DllCanUnloadNow) and global data should always be accessed by the same apartment. COM creates such objects in the main apartment of the client, giving the main apartment direct access to the object's pointers. Calls from the other apartments use interthread marshaling to go from the proxy to the stub in the main apartment and then to the object. This allows COM to synchronize calls to the object. Interthread calls are slow, so it is recommended that these servers be rewritten to support multiple apartments. single-threaded的全称应该是single-thread-per-process。

COM Fundamentals

COM requires that the only way to gain access to the methods of an interface is through a pointer to the interface. An interface definition specifies the interface's member functions, called methods, their return types, the number and types of their parameters, and what they must do. There is no implementation associated with an interface. COM interfaces are immutable—You cannot define a new version of an old interface and give it the same identifier. Adding or removing methods of an interface or changing semantics creates a new interface, not a new version of an old interface. Therefore, a new interface cannot conflict with an old interface. However, objects can support multiple interfaces simultaneously and can expose interfaces that are successive revisions of an interface, with different identifiers. Thus, each interface is a separate contract, and systemwide objects need not be concerned about whether the version of the interface they are calling is the one they expect. The interface ID (IID) defines the interface contract explicitly and uniquely. All COM objects must implement the IUnknown interface。 For any given object instance, a call to QueryInterface(IID_IUnknown, ...) must always return the same physical pointer value(((IUnknown*)*ppv)->AddRef(); ). This allows you to call QueryInterface(IID_IUnknown, ...) on any two interfaces and compare the results to determine whether they point to the same instance of an object. Containment/Delegation(包容/托管) the outer object explicitly delegates implementation to the inner object's methods,That is, the outer object uses the inner object's services to implement itself.显然所有com对象都支持包容。 Aggregation is actually a specialized case of containment/delegation.the outer object exposes interfaces from the inner object as if they were implemented on the outer object itself. The following rules apply to creating an aggregable object: The aggregable (or inner) object's implementation of QueryInterface, AddRef, and Release for its IUnknown interface controls the inner object's reference count, and this implementation must not delegate to the outer object's unknown (the controlling IUnknown). The aggregable (or inner) object's implementation of QueryInterface, AddRef, and Release for its other interfaces must delegate to the controlling IUnknown and must not directly affect the inner object's reference count. The inner IUnknown must implement QueryInterface only for the inner object. The aggregable object must not call AddRef when holding a reference to the controlling IUnknown pointer. When the object is created, if any interface other than IUnknown is requested, the creation must fail with E_NOINTERFACE.