Changeset 6850 in vbox for trunk/src/libs/xpcom18a4/ipc/ipcd/extensions
- Timestamp:
- Feb 7, 2008 3:59:12 PM (17 years ago)
- Location:
- trunk/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.cpp
r5970 r6850 69 69 // XXX TODO: 70 70 // 1. add thread affinity field to SETUP messages 71 // 2. support array parameters72 71 73 72 //----------------------------------------------------------------------------- … … 85 84 86 85 #define DCON_WAIT_TIMEOUT PR_INTERVAL_NO_TIMEOUT 87 88 // used elsewhere like nsAtomTable to safely represent the integral value89 // of an address.90 typedef unsigned long PtrBits;91 86 92 87 //----------------------------------------------------------------------------- … … 274 269 return count; 275 270 } 276 271 277 272 private: 278 273 nsAutoRefCnt mRefCnt; … … 410 405 411 406 case nsXPTType::T_ARRAY: 412 LOG(("array types are not yet supported\n")); 413 return NS_ERROR_NOT_IMPLEMENTED; 407 // arrays are serialized after all other params outside this routine 408 break; 409 410 case nsXPTType::T_VOID: 411 case nsXPTType::T_PSTRING_SIZE_IS: 412 case nsXPTType::T_PWSTRING_SIZE_IS: 413 default: 414 LOG(("unexpected parameter type: %d\n", t.TagPart())); 415 return NS_ERROR_UNEXPECTED; 416 } 417 return NS_OK; 418 } 419 420 static nsresult 421 DeserializeParam(ipcMessageReader &reader, const nsXPTType &t, nsXPTCVariant &v) 422 { 423 // defaults 424 v.ptr = nsnull; 425 v.type = t; 426 v.flags = 0; 427 428 switch (t.TagPart()) 429 { 430 case nsXPTType::T_I8: 431 case nsXPTType::T_U8: 432 v.val.u8 = reader.GetInt8(); 433 break; 434 435 case nsXPTType::T_I16: 436 case nsXPTType::T_U16: 437 v.val.u16 = reader.GetInt16(); 438 break; 439 440 case nsXPTType::T_I32: 441 case nsXPTType::T_U32: 442 v.val.u32 = reader.GetInt32(); 443 break; 444 445 case nsXPTType::T_I64: 446 case nsXPTType::T_U64: 447 reader.GetBytes(&v.val.u64, sizeof(v.val.u64)); 448 break; 449 450 case nsXPTType::T_FLOAT: 451 reader.GetBytes(&v.val.f, sizeof(v.val.f)); 452 break; 453 454 case nsXPTType::T_DOUBLE: 455 reader.GetBytes(&v.val.d, sizeof(v.val.d)); 456 break; 457 458 case nsXPTType::T_BOOL: 459 reader.GetBytes(&v.val.b, sizeof(v.val.b)); 460 break; 461 462 case nsXPTType::T_CHAR: 463 reader.GetBytes(&v.val.c, sizeof(v.val.c)); 464 break; 465 466 case nsXPTType::T_WCHAR: 467 reader.GetBytes(&v.val.wc, sizeof(v.val.wc)); 468 break; 469 470 case nsXPTType::T_IID: 471 { 472 nsID *buf = (nsID *) nsMemory::Alloc(sizeof(nsID)); 473 reader.GetBytes(buf, sizeof(nsID)); 474 v.val.p = buf; 475 v.SetValIsAllocated(); 476 } 477 break; 478 479 case nsXPTType::T_CHAR_STR: 480 { 481 PRUint32 len = reader.GetInt32(); 482 if (len == (PRUint32) -1) 483 { 484 // it's a null string 485 v.val.p = nsnull; 486 } 487 else 488 { 489 char *buf = (char *) nsMemory::Alloc(len + 1); 490 reader.GetBytes(buf, len); 491 buf[len] = char(0); 492 493 v.val.p = buf; 494 v.SetValIsAllocated(); 495 } 496 } 497 break; 498 499 case nsXPTType::T_WCHAR_STR: 500 { 501 PRUint32 len = reader.GetInt32(); 502 if (len == (PRUint32) -1) 503 { 504 // it's a null string 505 v.val.p = nsnull; 506 } 507 else 508 { 509 PRUnichar *buf = (PRUnichar *) nsMemory::Alloc(len + 2); 510 reader.GetBytes(buf, len); 511 buf[len / 2] = PRUnichar(0); 512 513 v.val.p = buf; 514 v.SetValIsAllocated(); 515 } 516 } 517 break; 518 519 case nsXPTType::T_INTERFACE: 520 case nsXPTType::T_INTERFACE_IS: 521 { 522 reader.GetBytes(&v.val.p, sizeof(void *)); 523 // stub creation will be handled outside this routine. we only 524 // deserialize the DConAddr into v.val.p temporarily. 525 } 526 break; 527 528 case nsXPTType::T_ASTRING: 529 case nsXPTType::T_DOMSTRING: 530 { 531 PRUint32 len = reader.GetInt32(); 532 533 nsString *str = new nsString(); 534 str->SetLength(len / 2); 535 PRUnichar *buf = str->BeginWriting(); 536 reader.GetBytes(buf, len); 537 538 v.val.p = str; 539 v.SetValIsDOMString(); 540 } 541 break; 542 543 case nsXPTType::T_UTF8STRING: 544 case nsXPTType::T_CSTRING: 545 { 546 PRUint32 len = reader.GetInt32(); 547 548 nsCString *str = new nsCString(); 549 str->SetLength(len); 550 char *buf = str->BeginWriting(); 551 reader.GetBytes(buf, len); 552 553 v.val.p = str; 554 555 // this distinction here is pretty pointless 556 if (t.TagPart() == nsXPTType::T_CSTRING) 557 v.SetValIsCString(); 558 else 559 v.SetValIsUTF8String(); 560 } 561 break; 562 563 case nsXPTType::T_ARRAY: 564 // arrays are deserialized after all other params outside this routine 565 break; 414 566 415 567 case nsXPTType::T_VOID: … … 424 576 425 577 static nsresult 426 DeserializeParam(ipcMessageReader &reader, const nsXPTType &t, nsXPTCVariant &v)427 {428 // defaults429 v.ptr = nsnull;430 v.type = t;431 v.flags = 0;432 433 switch (t.TagPart())434 {435 case nsXPTType::T_I8:436 case nsXPTType::T_U8:437 v.val.u8 = reader.GetInt8();438 break;439 440 case nsXPTType::T_I16:441 case nsXPTType::T_U16:442 v.val.u16 = reader.GetInt16();443 break;444 445 case nsXPTType::T_I32:446 case nsXPTType::T_U32:447 v.val.u32 = reader.GetInt32();448 break;449 450 case nsXPTType::T_I64:451 case nsXPTType::T_U64:452 reader.GetBytes(&v.val.u64, sizeof(v.val.u64));453 break;454 455 case nsXPTType::T_FLOAT:456 reader.GetBytes(&v.val.f, sizeof(v.val.f));457 break;458 459 case nsXPTType::T_DOUBLE:460 reader.GetBytes(&v.val.d, sizeof(v.val.d));461 break;462 463 case nsXPTType::T_BOOL:464 reader.GetBytes(&v.val.b, sizeof(v.val.b));465 break;466 467 case nsXPTType::T_CHAR:468 reader.GetBytes(&v.val.c, sizeof(v.val.c));469 break;470 471 case nsXPTType::T_WCHAR:472 reader.GetBytes(&v.val.wc, sizeof(v.val.wc));473 break;474 475 case nsXPTType::T_IID:476 {477 nsID *buf = (nsID *) nsMemory::Alloc(sizeof(nsID));478 reader.GetBytes(buf, sizeof(nsID));479 v.val.p = v.ptr = buf;480 v.flags = nsXPTCVariant::PTR_IS_DATA | nsXPTCVariant::VAL_IS_ALLOCD;481 }482 break;483 484 case nsXPTType::T_CHAR_STR:485 {486 PRUint32 len = reader.GetInt32();487 if (len == (PRUint32) -1)488 {489 // it's a null string490 v.val.p = v.ptr = 0;491 v.flags = nsXPTCVariant::PTR_IS_DATA;492 }493 else494 {495 char *buf = (char *) nsMemory::Alloc(len + 1);496 reader.GetBytes(buf, len);497 buf[len] = char(0);498 499 v.val.p = v.ptr = buf;500 v.flags = nsXPTCVariant::PTR_IS_DATA | nsXPTCVariant::VAL_IS_ALLOCD;501 }502 }503 break;504 505 case nsXPTType::T_WCHAR_STR:506 {507 PRUint32 len = reader.GetInt32();508 if (len == (PRUint32) -1)509 {510 // it's a null string511 v.val.p = v.ptr = 0;512 v.flags = nsXPTCVariant::PTR_IS_DATA;513 }514 else515 {516 PRUnichar *buf = (PRUnichar *) nsMemory::Alloc(len + 2);517 reader.GetBytes(buf, len);518 buf[len / 2] = PRUnichar(0);519 520 v.val.p = v.ptr = buf;521 v.flags = nsXPTCVariant::PTR_IS_DATA | nsXPTCVariant::VAL_IS_ALLOCD;522 }523 }524 break;525 526 case nsXPTType::T_INTERFACE:527 case nsXPTType::T_INTERFACE_IS:528 {529 reader.GetBytes(&v.ptr, sizeof(void *));530 v.val.p = nsnull;531 v.flags = nsXPTCVariant::PTR_IS_DATA;532 }533 break;534 535 case nsXPTType::T_ASTRING:536 case nsXPTType::T_DOMSTRING:537 {538 PRUint32 len = reader.GetInt32();539 540 nsString *str = new nsString();541 str->SetLength(len / 2);542 PRUnichar *buf = str->BeginWriting();543 reader.GetBytes(buf, len);544 545 v.val.p = v.ptr = str;546 v.flags = nsXPTCVariant::PTR_IS_DATA | nsXPTCVariant::VAL_IS_DOMSTR;547 }548 break;549 550 case nsXPTType::T_UTF8STRING:551 case nsXPTType::T_CSTRING:552 {553 PRUint32 len = reader.GetInt32();554 555 nsCString *str = new nsCString();556 str->SetLength(len);557 char *buf = str->BeginWriting();558 reader.GetBytes(buf, len);559 560 v.val.p = v.ptr = str;561 v.flags = nsXPTCVariant::PTR_IS_DATA;562 563 // this distinction here is pretty pointless564 if (t.TagPart() == nsXPTType::T_CSTRING)565 v.flags |= nsXPTCVariant::VAL_IS_CSTR;566 else567 v.flags |= nsXPTCVariant::VAL_IS_UTF8STR;568 }569 break;570 571 case nsXPTType::T_ARRAY:572 LOG(("array types are not yet supported\n"));573 return NS_ERROR_NOT_IMPLEMENTED;574 575 case nsXPTType::T_VOID:576 case nsXPTType::T_PSTRING_SIZE_IS:577 case nsXPTType::T_PWSTRING_SIZE_IS:578 default:579 LOG(("unexpected parameter type\n"));580 return NS_ERROR_UNEXPECTED;581 }582 return NS_OK;583 }584 585 static nsresult586 578 SetupParam(const nsXPTParamInfo &p, nsXPTCVariant &v) 587 579 { … … 591 583 { 592 584 v.ptr = nsnull; 585 v.flags = 0; 593 586 594 587 switch (t.TagPart()) … … 596 589 case nsXPTType::T_ASTRING: 597 590 case nsXPTType::T_DOMSTRING: 598 v. ptr= new nsString();599 if (!v. ptr)591 v.val.p = new nsString(); 592 if (!v.val.p) 600 593 return NS_ERROR_OUT_OF_MEMORY; 601 v.val.p = v.ptr;602 594 v.type = t; 603 v. flags = nsXPTCVariant::PTR_IS_DATA | nsXPTCVariant::VAL_IS_DOMSTR;595 v.SetValIsDOMString(); 604 596 break; 605 597 606 598 case nsXPTType::T_UTF8STRING: 607 599 case nsXPTType::T_CSTRING: 608 v. ptr= new nsCString();609 if (!v. ptr)600 v.val.p = new nsCString(); 601 if (!v.val.p) 610 602 return NS_ERROR_OUT_OF_MEMORY; 611 v.val.p = v.ptr;612 603 v.type = t; 613 v. flags = nsXPTCVariant::PTR_IS_DATA | nsXPTCVariant::VAL_IS_CSTR;604 v.SetValIsCString(); 614 605 break; 615 606 … … 624 615 v.ptr = &v.val; 625 616 v.type = t; 626 v.flags = nsXPTCVariant::PTR_IS_DATA; 627 628 // nsID, string and wstring types are not understood as dippers (see 629 // DIPPER_TYPE in xpidl.h) but they behave like dippers too. Therefore we 630 // need to treat them so manually. 617 v.flags = 0; 618 v.SetPtrIsData(); 619 620 // the ownership of output nsID, string, wstring, interface pointers and 621 // arrays is transferred to the receiving party. Therefore, we need to 622 // instruct FinishParam() to perform a cleanup after serializing them. 631 623 switch (t.TagPart()) 632 624 { … … 634 626 case nsXPTType::T_CHAR_STR: 635 627 case nsXPTType::T_WCHAR_STR: 636 // add VAL_IS_ALLOCD to cause FinishParam() to do cleanup 637 v.flags |= nsXPTCVariant::VAL_IS_ALLOCD; 628 case nsXPTType::T_ARRAY: 629 v.SetValIsAllocated(); 630 break; 631 case nsXPTType::T_INTERFACE: 632 case nsXPTType::T_INTERFACE_IS: 633 v.SetValIsInterface(); 638 634 break; 639 635 default: … … 652 648 653 649 if (v.IsValAllocated()) 654 650 nsMemory::Free(v.val.p); 655 651 else if (v.IsValInterface()) 656 652 ((nsISupports *) v.val.p)->Release(); … … 797 793 798 794 case nsXPTType::T_ARRAY: 799 LOG(("array types are not yet supported\n"));800 return NS_ERROR_NOT_IMPLEMENTED;795 // arrays are deserialized after all other params outside this routine 796 break; 801 797 802 798 case nsXPTType::T_VOID: … … 808 804 } 809 805 return NS_OK; 806 } 807 808 //----------------------------------------------------------------------------- 809 // 810 // Returns an element from the nsXPTCMiniVariant array by properly casting it to 811 // nsXPTCVariant when requested 812 #define GET_PARAM(params, isXPTCVariantArray, idx) \ 813 (isXPTCVariantArray ? ((nsXPTCVariant *) params) [idx] : params [idx]) 814 815 // isResult is PR_TRUE if the size_is and length_is params are out or retval 816 // so that nsXPTCMiniVariants contain pointers to their locations instead of the 817 // values themselves. 818 static nsresult 819 GetArrayParamInfo(nsIInterfaceInfo *iinfo, uint16 methodIndex, 820 const nsXPTMethodInfo &methodInfo, nsXPTCMiniVariant *params, 821 PRBool isXPTCVariantArray, const nsXPTParamInfo ¶mInfo, 822 PRBool isResult, PRUint32 &size, PRUint32 &length, 823 nsXPTType &elemType) 824 { 825 // XXX multidimensional arrays are not supported so dimension is always 0 for 826 // getting the size_is argument number of the array itself and 1 for getting 827 // the type of elements stored in the array. 828 829 nsresult rv; 830 831 // get the array size 832 PRUint8 sizeArg; 833 rv = iinfo->GetSizeIsArgNumberForParam(methodIndex, ¶mInfo, 0, &sizeArg); 834 if (NS_FAILED(rv)) 835 return rv; 836 837 // get the number of valid elements 838 PRUint8 lenArg; 839 rv = iinfo->GetLengthIsArgNumberForParam(methodIndex, ¶mInfo, 0, &lenArg); 840 if (NS_FAILED(rv)) 841 return rv; 842 843 // according to XPT specs 844 // (http://www.mozilla.org/scriptable/typelib_file.html), size_is and 845 // length_is for arrays is always uint32. Check this too. 846 { 847 nsXPTParamInfo pi = methodInfo.GetParam (sizeArg); 848 if (pi.GetType().TagPart() != nsXPTType::T_U32) 849 { 850 LOG(("unexpected size_is() parameter type: $d\n", 851 pi.GetType().TagPart())); 852 return NS_ERROR_UNEXPECTED; 853 } 854 855 pi = methodInfo.GetParam (lenArg); 856 if (pi.GetType().TagPart() != nsXPTType::T_U32) 857 { 858 LOG(("unexpected length_is() parameter type: $d\n", 859 pi.GetType().TagPart())); 860 return NS_ERROR_UNEXPECTED; 861 } 862 } 863 864 if (isResult) 865 { 866 length = *((PRUint32 *) GET_PARAM(params,isXPTCVariantArray, lenArg).val.p); 867 size = *((PRUint32 *) GET_PARAM(params, isXPTCVariantArray, sizeArg).val.p); 868 } 869 else 870 { 871 length = GET_PARAM(params, isXPTCVariantArray, lenArg).val.u32; 872 size = GET_PARAM(params, isXPTCVariantArray, sizeArg).val.u32; 873 } 874 875 if (length > size) 876 { 877 NS_WARNING("length_is() value is greater than size_is() value"); 878 length = size; 879 } 880 881 // get type of array elements 882 rv = iinfo->GetTypeForParam(methodIndex, ¶mInfo, 1, &elemType); 883 if (NS_FAILED(rv)) 884 return rv; 885 886 if (elemType.IsArithmetic() && 887 (elemType.IsPointer() || elemType.IsUniquePointer() || 888 elemType.IsReference())) 889 { 890 LOG(("arrays of pointers and references to arithmetic types are " 891 "not yet supported\n")); 892 return NS_ERROR_NOT_IMPLEMENTED; 893 } 894 895 if (elemType.IsArray()) 896 { 897 LOG(("multidimensional arrays are not yet supported\n")); 898 return NS_ERROR_NOT_IMPLEMENTED; 899 } 900 901 return NS_OK; 902 } 903 904 static nsresult 905 GetTypeSize(const nsXPTType &type, PRUint32 &size, PRBool &isSimple) 906 { 907 // get the type size in bytes 908 size = 0; 909 isSimple = PR_TRUE; 910 switch (type.TagPart()) 911 { 912 case nsXPTType::T_I8: size = sizeof(PRInt8); break; 913 case nsXPTType::T_I16: size = sizeof(PRInt16); break; 914 case nsXPTType::T_I32: size = sizeof(PRInt32); break; 915 case nsXPTType::T_I64: size = sizeof(PRInt64); break; 916 case nsXPTType::T_U8: size = sizeof(PRUint8); break; 917 case nsXPTType::T_U16: size = sizeof(PRUint16); break; 918 case nsXPTType::T_U32: size = sizeof(PRUint32); break; 919 case nsXPTType::T_U64: size = sizeof(PRUint64); break; 920 case nsXPTType::T_FLOAT: size = sizeof(float); break; 921 case nsXPTType::T_DOUBLE: size = sizeof(double); break; 922 case nsXPTType::T_BOOL: size = sizeof(PRBool); break; 923 case nsXPTType::T_CHAR: size = sizeof(char); break; 924 case nsXPTType::T_WCHAR: size = sizeof(PRUnichar); break; 925 case nsXPTType::T_IID: /* fall through */ 926 case nsXPTType::T_CHAR_STR: /* fall through */ 927 case nsXPTType::T_WCHAR_STR: /* fall through */ 928 case nsXPTType::T_INTERFACE: /* fall through */ 929 case nsXPTType::T_INTERFACE_IS: /* fall through */ 930 case nsXPTType::T_ASTRING: /* fall through */ 931 case nsXPTType::T_DOMSTRING: /* fall through */ 932 case nsXPTType::T_UTF8STRING: /* fall through */ 933 case nsXPTType::T_CSTRING: /* fall through */ 934 size = sizeof(void *); 935 isSimple = PR_FALSE; 936 break; 937 default: 938 LOG(("unexpected parameter type: %d\n", type.TagPart())); 939 return NS_ERROR_UNEXPECTED; 940 } 941 942 return NS_OK; 943 } 944 945 static nsresult 946 SerializeArrayParam(ipcDConnectService *dConnect, 947 ipcMessageWriter &writer, PRUint32 peerID, 948 nsIInterfaceInfo *iinfo, uint16 methodIndex, 949 const nsXPTMethodInfo &methodInfo, 950 nsXPTCMiniVariant *params, PRBool isXPTCVariantArray, 951 const nsXPTParamInfo ¶mInfo, 952 void *array, nsVoidArray &wrappers) 953 { 954 if (!array) 955 { 956 // put 0 to indicate null array 957 writer.PutInt8(0); 958 return NS_OK; 959 } 960 961 // put 1 to indicate non-null array 962 writer.PutInt8(1); 963 964 PRUint32 size = 0; 965 PRUint32 length = 0; 966 nsXPTType elemType; 967 968 nsresult rv = GetArrayParamInfo(iinfo, methodIndex, methodInfo, params, 969 isXPTCVariantArray, paramInfo, PR_FALSE, 970 size, length, elemType); 971 if (NS_FAILED (rv)) 972 return rv; 973 974 PRUint32 elemSize = 0; 975 PRBool isSimple = PR_TRUE; 976 rv = GetTypeSize(elemType, elemSize, isSimple); 977 if (NS_FAILED (rv)) 978 return rv; 979 980 if (isSimple) 981 { 982 // this is a simple arithmetic type, write the whole array at once 983 writer.PutBytes(array, length * elemSize); 984 return NS_OK; 985 } 986 987 // iterate over valid (length_is) elements of the array 988 // and serialize each of them 989 nsXPTCMiniVariant v; 990 for (PRUint32 i = 0; i < length; ++i) 991 { 992 v.val.p = ((void **) array) [i]; 993 994 if (elemType.IsInterfacePointer()) 995 { 996 nsID iid; 997 rv = dConnect->GetIIDForMethodParam(iinfo, &methodInfo, paramInfo, elemType, 998 methodIndex, params, isXPTCVariantArray, 999 iid); 1000 if (NS_SUCCEEDED(rv)) 1001 rv = dConnect->SerializeInterfaceParam(writer, peerID, iid, 1002 (nsISupports *) v.val.p, 1003 wrappers); 1004 } 1005 else 1006 rv = SerializeParam(writer, elemType, v); 1007 1008 if (NS_FAILED(rv)) 1009 return rv; 1010 } 1011 1012 return NS_OK; 1013 } 1014 1015 // isResult is PR_TRUE if the array param is out or retval 1016 static nsresult 1017 DeserializeArrayParam(ipcDConnectService *dConnect, 1018 ipcMessageReader &reader, PRUint32 peerID, 1019 nsIInterfaceInfo *iinfo, uint16 methodIndex, 1020 const nsXPTMethodInfo &methodInfo, 1021 nsXPTCMiniVariant *params, PRBool isXPTCVariantArray, 1022 const nsXPTParamInfo ¶mInfo, 1023 PRBool isResult, void *&array) 1024 { 1025 PRUint32 size = 0; 1026 PRUint32 length = 0; 1027 nsXPTType elemType; 1028 1029 nsresult rv = GetArrayParamInfo(iinfo, methodIndex, methodInfo, params, 1030 isXPTCVariantArray, paramInfo, isResult, 1031 size, length, elemType); 1032 if (NS_FAILED(rv)) 1033 return rv; 1034 1035 PRUint8 prefix = reader.GetInt8(); 1036 if (prefix == 0) 1037 { 1038 // it's a null array 1039 array = nsnull; 1040 return NS_OK; 1041 } 1042 // sanity 1043 if (prefix != 1) 1044 { 1045 LOG(("unexpected array prefix: %u\n", prefix)); 1046 return NS_ERROR_UNEXPECTED; 1047 } 1048 1049 PRUint32 elemSize = 0; 1050 PRBool isSimple = PR_TRUE; 1051 rv = GetTypeSize(elemType, elemSize, isSimple); 1052 if (NS_FAILED (rv)) 1053 return rv; 1054 1055 void *arr = nsMemory::Alloc(size * elemSize); 1056 if (arr == nsnull) 1057 return NS_ERROR_OUT_OF_MEMORY; 1058 1059 // initialize the unused space of the array with zeroes 1060 if (length < size) 1061 memset(((PRUint8 *) arr) + length * elemSize, 0, 1062 (size - length) * elemSize); 1063 1064 if (isSimple) 1065 { 1066 // this is a simple arithmetic type, read the whole array at once 1067 reader.GetBytes(arr, length * elemSize); 1068 1069 array = arr; 1070 return NS_OK; 1071 } 1072 1073 // iterate over valid (length_is) elements of the array 1074 // and deserialize each of them individually 1075 nsXPTCVariant v; 1076 for (PRUint32 i = 0; i < length; ++i) 1077 { 1078 rv = DeserializeParam(reader, elemType, v); 1079 1080 if (NS_SUCCEEDED(rv) && elemType.IsInterfacePointer()) 1081 { 1082 // grab the DConAddr value temporarily stored in the param 1083 PtrBits bits = (PtrBits) v.val.p; 1084 1085 // DeserializeInterfaceParamBits needs IID only if it's a remote object 1086 nsID iid; 1087 if (bits & PTRBITS_REMOTE_BIT) 1088 rv = dConnect->GetIIDForMethodParam(iinfo, &methodInfo, paramInfo, 1089 elemType, methodIndex, 1090 params, isXPTCVariantArray, iid); 1091 if (NS_SUCCEEDED(rv)) 1092 { 1093 nsISupports *obj = nsnull; 1094 rv = dConnect->DeserializeInterfaceParamBits(bits, peerID, iid, obj); 1095 if (NS_SUCCEEDED(rv)) 1096 v.val.p = obj; 1097 } 1098 } 1099 1100 if (NS_FAILED(rv)) 1101 break; 1102 1103 // note that we discard extended param informaton provided by nsXPTCVariant 1104 // and will have to "reconstruct" it from the type tag in FinishArrayParam() 1105 ((void **) arr) [i] = v.val.p; 1106 } 1107 1108 if (NS_FAILED(rv)) 1109 nsMemory::Free(arr); 1110 else 1111 array = arr; 1112 1113 return rv; 1114 } 1115 1116 static void 1117 FinishArrayParam(nsIInterfaceInfo *iinfo, uint16 methodIndex, 1118 const nsXPTMethodInfo &methodInfo, nsXPTCMiniVariant *params, 1119 PRBool isXPTCVariantArray, const nsXPTParamInfo ¶mInfo, 1120 const nsXPTCMiniVariant &arrayVal) 1121 { 1122 // nothing to do for a null array 1123 void *arr = arrayVal.val.p; 1124 if (!arr) 1125 return; 1126 1127 PRUint32 size = 0; 1128 PRUint32 length = 0; 1129 nsXPTType elemType; 1130 1131 // note that FinishArrayParam is called only from OnInvoke to free memory 1132 // after the call has been served. When OnInvoke sets up out and retval 1133 // parameters for the real method, it passes pointers to the nsXPTCMiniVariant 1134 // elements of the params array themselves so that they will eventually 1135 // receive the returned values. For this reason, both in 'in' param and 1136 // 'out/retaval' param cases, size_is and length_is may be read by 1137 // GetArrayParamInfo() by value. Therefore, isResult is always PR_FALSE. 1138 nsresult rv = GetArrayParamInfo(iinfo, methodIndex, methodInfo, params, 1139 isXPTCVariantArray, paramInfo, PR_FALSE, 1140 size, length, elemType); 1141 if (NS_FAILED (rv)) 1142 return; 1143 1144 nsXPTCVariant v; 1145 v.ptr = nsnull; 1146 v.flags = 0; 1147 1148 // iterate over valid (length_is) elements of the array 1149 // and free each of them 1150 for (PRUint32 i = 0; i < length; ++i) 1151 { 1152 v.type = elemType.TagPart(); 1153 1154 switch (elemType.TagPart()) 1155 { 1156 case nsXPTType::T_I8: /* fall through */ 1157 case nsXPTType::T_I16: /* fall through */ 1158 case nsXPTType::T_I32: /* fall through */ 1159 case nsXPTType::T_I64: /* fall through */ 1160 case nsXPTType::T_U8: /* fall through */ 1161 case nsXPTType::T_U16: /* fall through */ 1162 case nsXPTType::T_U32: /* fall through */ 1163 case nsXPTType::T_U64: /* fall through */ 1164 case nsXPTType::T_FLOAT: /* fall through */ 1165 case nsXPTType::T_DOUBLE: /* fall through */ 1166 case nsXPTType::T_BOOL: /* fall through */ 1167 case nsXPTType::T_CHAR: /* fall through */ 1168 case nsXPTType::T_WCHAR: /* fall through */ 1169 // nothing to free for arithmetic types 1170 continue; 1171 case nsXPTType::T_IID: /* fall through */ 1172 case nsXPTType::T_CHAR_STR: /* fall through */ 1173 case nsXPTType::T_WCHAR_STR: /* fall through */ 1174 v.val.p = ((void **) arr) [i]; 1175 v.SetValIsAllocated(); 1176 break; 1177 case nsXPTType::T_INTERFACE: /* fall through */ 1178 case nsXPTType::T_INTERFACE_IS: /* fall through */ 1179 v.val.p = ((void **) arr) [i]; 1180 v.SetValIsInterface(); 1181 break; 1182 case nsXPTType::T_ASTRING: /* fall through */ 1183 case nsXPTType::T_DOMSTRING: /* fall through */ 1184 v.val.p = ((void **) arr) [i]; 1185 v.SetValIsDOMString(); 1186 break; 1187 case nsXPTType::T_UTF8STRING: /* fall through */ 1188 v.val.p = ((void **) arr) [i]; 1189 v.SetValIsUTF8String(); 1190 break; 1191 case nsXPTType::T_CSTRING: /* fall through */ 1192 v.val.p = ((void **) arr) [i]; 1193 v.SetValIsCString(); 1194 break; 1195 default: 1196 LOG(("unexpected parameter type: %d\n", elemType.TagPart())); 1197 return; 1198 } 1199 1200 FinishParam(v); 1201 } 810 1202 } 811 1203 … … 995 1387 return DConnectStubKey::Key(mPeerID, mInstance); 996 1388 } 997 1389 998 1390 NS_IMETHOD_(nsrefcnt) AddRefIPC(); 999 1391 1000 1392 private: 1001 1393 nsCOMPtr<nsIInterfaceInfo> mIInfo; … … 1006 1398 // the "client id" of our IPC peer. this guy owns the real object. 1007 1399 PRUint32 mPeerID; 1008 1400 1009 1401 // cached nsISupports stub for this object 1010 1402 DConnectStub *mCachedISupports; 1011 1403 1012 1404 // stack of reference counter values (protected by 1013 1405 // ipcDConnectService::StubLock()) … … 1161 1553 // the wrapper from the instance map on failure) 1162 1554 wrapper->AddRefIPC(); 1163 1555 1164 1556 if (!wrappers.AppendElement(wrapper)) 1165 1557 { … … 1171 1563 // wrapper remains referenced when passing it to the client 1172 1564 // (will be released upon DCON_OP_RELEASE) 1173 1174 // send address of the instance wrapper, and set the low bit 1175 // to indicate that this is aninstance wrapper.1176 PtrBits bits = ((PtrBits) wrapper) | 0x1;1565 1566 // send address of the instance wrapper, and set the low bit to indicate 1567 // to the remote party that this is a remote instance wrapper. 1568 PtrBits bits = ((PtrBits) wrapper) | PTRBITS_REMOTE_BIT; 1177 1569 writer.PutBytes(&bits, sizeof(bits)); 1178 1570 } 1179 1571 NS_IF_RELEASE(stub); 1180 1572 } 1573 return NS_OK; 1574 } 1575 1576 // NOTE: peer and iid are ignored if bits doesn't contain PTRBITS_REMOTE_BIT 1577 nsresult 1578 ipcDConnectService::DeserializeInterfaceParamBits(PtrBits bits, PRUint32 peer, 1579 const nsID &iid, 1580 nsISupports *&obj) 1581 { 1582 nsresult rv; 1583 1584 obj = nsnull; 1585 1586 if (bits & PTRBITS_REMOTE_BIT) 1587 { 1588 // pointer is to a remote object. we need to build a stub. 1589 1590 bits &= ~PTRBITS_REMOTE_BIT; 1591 1592 DConnectStub *stub; 1593 rv = CreateStub(iid, peer, (DConAddr) bits, &stub); 1594 if (NS_SUCCEEDED(rv)) 1595 obj = stub; 1596 } 1597 else if (bits) 1598 { 1599 // pointer is to one of our instance wrappers. Replace it with the 1600 // real instance. 1601 1602 DConnectInstance *wrapper = (DConnectInstance *) bits; 1603 // make sure we've been sent a valid wrapper 1604 if (!CheckInstanceAndAddRef(wrapper)) 1605 { 1606 NS_NOTREACHED("instance wrapper not found"); 1607 return NS_ERROR_INVALID_ARG; 1608 } 1609 obj = wrapper->RealInstance(); 1610 NS_ADDREF(obj); 1611 NS_RELEASE(wrapper); 1612 } 1613 else 1614 { 1615 // obj is alredy nsnull 1616 } 1617 1181 1618 return NS_OK; 1182 1619 } … … 1434 1871 // the wrapper from the instance map on failure) 1435 1872 wrapper->AddRefIPC(); 1436 1873 1437 1874 if (!wrappers.AppendElement(wrapper)) 1438 1875 { … … 1445 1882 // (will be released upon DCON_OP_RELEASE) 1446 1883 1447 // send address of the instance wrapper, and set the low bit 1448 // to indicate that this is aninstance wrapper.1449 PtrBits bits = ((PtrBits) wrapper) | 0x1;1884 // send address of the instance wrapper, and set the low bit to indicate 1885 // to the remote party that this is a remote instance wrapper. 1886 PtrBits bits = ((PtrBits) wrapper) | PTRBITS_REMOTE_BIT; 1450 1887 writer.PutBytes(&bits, sizeof(bits)); 1451 1888 … … 1544 1981 PtrBits bits = (PtrBits) (instance); 1545 1982 1546 if (bits & 0x1)1983 if (bits & PTRBITS_REMOTE_BIT) 1547 1984 { 1548 1985 // pointer is a peer-side exception instance wrapper, … … 1585 2022 else 1586 2023 { 1587 DConAddr addr = (DConAddr) (bits & ~ 0x1);2024 DConAddr addr = (DConAddr) (bits & ~PTRBITS_REMOTE_BIT); 1588 2025 nsRefPtr<DConnectStub> stub; 1589 2026 rv = CreateStub(nsIException::GetIID(), peer, addr, … … 1648 2085 LOG(("{%p} DConnectStub::<dtor>(): peer=%d instance=%p {%s}\n", 1649 2086 this, mPeerID, mInstance, name)); 1650 #endif 1651 2087 #endif 2088 1652 2089 // release the cached nsISupports instance if it's not the same object 1653 2090 if (mCachedISupports != 0 && mCachedISupports != this) … … 1687 2124 { 1688 2125 nsrefcnt top = (nsrefcnt) (long) mRefCntLevels.Peek(); 1689 NS_ASSERTION(top <= count + 1, "refcount is beyond the top level"); 2126 NS_ASSERTION(top <= count + 1, "refcount is beyond the top level"); 1690 2127 1691 2128 if (top == count + 1) … … 1708 2145 // leave the lock before sending a message 1709 2146 stubLock.unlock(); 1710 2147 1711 2148 nsresult rv; 1712 2149 … … 1716 2153 msg.request_index = 0; // not used, set to some unused value 1717 2154 msg.instance = mInstance; 1718 2155 1719 2156 // fire off asynchronously... we don't expect any response to this message. 1720 2157 rv = IPC_SendMessage(mPeerID, kDConnectTargetID, … … 1730 2167 NS_LOG_RELEASE(this, count, "DConnectStub"); 1731 2168 } 1732 2169 1733 2170 if (0 == count) 1734 2171 { … … 1830 2267 // stub lock remains held until we've queried the peer 1831 2268 } 1832 2269 1833 2270 // else, we need to query the peer object by making an IPC call 1834 2271 … … 1901 2338 return rv; 1902 2339 nsCOMPtr <nsIExceptionManager> em; 1903 rv = es->GetCurrentExceptionManager (getter_AddRefs(em)); 2340 rv = es->GetCurrentExceptionManager (getter_AddRefs(em)); 1904 2341 if (NS_FAILED (rv)) 1905 2342 return rv; … … 1907 2344 if (NS_FAILED (rv)) 1908 2345 return rv; 1909 2346 1910 2347 // ensure ipcDConnectService is not deleted before we finish 1911 2348 nsRefPtr <ipcDConnectService> dConnect (ipcDConnectService::GetInstance()); … … 1951 2388 nsID iid; 1952 2389 rv = dConnect->GetIIDForMethodParam(mIInfo, aInfo, paramInfo, type, 1953 aMethodIndex, i,aParams, PR_FALSE, iid);2390 aMethodIndex, aParams, PR_FALSE, iid); 1954 2391 if (NS_SUCCEEDED(rv)) 1955 2392 rv = dConnect->SerializeInterfaceParam(writer, mPeerID, iid, … … 1967 2404 // report error early if NULL pointer is passed as an output parameter 1968 2405 return NS_ERROR_NULL_POINTER; 2406 } 2407 } 2408 2409 // serialize input array parameters after everything else since the 2410 // deserialization procedure will need to get a size_is value which may be 2411 // stored in any preceeding or following param 2412 for (i=0; i<paramCount; ++i) 2413 { 2414 const nsXPTParamInfo ¶mInfo = aInfo->GetParam(i); 2415 2416 if (paramInfo.GetType().IsArray() && 2417 paramInfo.IsIn() && !paramInfo.IsDipper()) 2418 { 2419 rv = SerializeArrayParam(dConnect, writer, mPeerID, mIInfo, aMethodIndex, 2420 *aInfo, aParams, PR_FALSE, paramInfo, 2421 aParams[i].val.p, wrappers); 2422 if (NS_FAILED(rv)) 2423 return rv; 1969 2424 } 1970 2425 } … … 2011 2466 if (NS_FAILED(rv)) 2012 2467 { 2013 NS_ASSERTION(completion.ParamsLen() >= sizeof(void*), 2468 NS_ASSERTION(completion.ParamsLen() == 0 || 2469 completion.ParamsLen() >= sizeof(void*), 2014 2470 "invalid nsIException serialization length"); 2015 2471 if (completion.ParamsLen() >= sizeof(void*)) … … 2047 2503 2048 2504 // fixup any interface pointers using a second pass so we can properly 2049 // handle INTERFACE_IS referencing an IID that is an out param! 2505 // handle INTERFACE_IS referencing an IID that is an out param! This pass is 2506 // also used to deserialize arrays (array data goes after all other params). 2050 2507 for (i=0; i<paramCount && NS_SUCCEEDED(rv); ++i) 2051 2508 { … … 2053 2510 if (aParams[i].val.p && (paramInfo.IsOut() || paramInfo.IsRetval())) 2054 2511 { 2512 void **pptr = (void **) aParams[i].val.p; 2055 2513 const nsXPTType &type = paramInfo.GetType(); 2056 2514 if (type.IsInterfacePointer()) 2057 2515 { 2058 PtrBits bits = (PtrBits) *((void **) aParams[i].val.p); 2059 if (bits & 0x1) 2516 // grab the DConAddr value temporarily stored in the param 2517 PtrBits bits = (PtrBits) *pptr; 2518 *pptr = nsnull; 2519 2520 // DeserializeInterfaceParamBits needs IID only if it's a remote object 2521 nsID iid; 2522 if (bits & PTRBITS_REMOTE_BIT) 2523 rv = dConnect->GetIIDForMethodParam(mIInfo, aInfo, paramInfo, type, 2524 aMethodIndex, aParams, PR_FALSE, 2525 iid); 2526 if (NS_SUCCEEDED(rv)) 2060 2527 { 2061 *((void **) aParams[i].val.p) = (void *) (bits & ~0x1); 2062 2063 nsID iid; 2064 rv = dConnect->GetIIDForMethodParam(mIInfo, aInfo, paramInfo, type, 2065 aMethodIndex, i, aParams, PR_FALSE, iid); 2066 if (NS_SUCCEEDED(rv)) 2067 { 2068 DConnectStub *stub; 2069 void **pptr = (void **) aParams[i].val.p; 2070 rv = dConnect->CreateStub(iid, mPeerID, (DConAddr) *pptr, &stub); 2528 nsISupports *obj = nsnull; 2529 rv = dConnect->DeserializeInterfaceParamBits(bits, mPeerID, iid, obj); 2071 2530 if (NS_SUCCEEDED(rv)) 2072 *((nsISupports **) aParams[i].val.p) = stub; 2073 } 2531 *pptr = obj; 2074 2532 } 2075 else if (bits) 2076 { 2077 // pointer is to one of our instance wrappers. Replace it with the 2078 // real instance. 2079 DConnectInstance *wrapper = (DConnectInstance *) bits; 2080 if (dConnect->CheckInstanceAndAddRef(wrapper)) 2081 { 2082 *((void **) aParams[i].val.p) = wrapper->RealInstance(); 2083 NS_ADDREF(wrapper->RealInstance()); 2084 wrapper->Release(); 2085 } 2086 else 2087 { 2088 NS_NOTREACHED("instance wrapper not found"); 2089 rv = NS_ERROR_INVALID_ARG; 2090 } 2091 } 2092 else 2093 { 2094 *((void **) aParams[i].val.p) = nsnull; 2095 } 2533 } 2534 else if (type.IsArray()) 2535 { 2536 void *array = nsnull; 2537 rv = DeserializeArrayParam(dConnect, reader, mPeerID, mIInfo, 2538 aMethodIndex, *aInfo, aParams, PR_FALSE, 2539 paramInfo, PR_TRUE, array); 2540 if (NS_SUCCEEDED(rv)) 2541 *pptr = array; 2096 2542 } 2097 2543 } … … 2379 2825 // (after which no DConnectInstances may exist), so forcibly delete them 2380 2826 // disregarding the reference counter 2381 2827 2382 2828 #ifdef IPC_LOGGING 2383 2829 const char *name; … … 2490 2936 printf("ipcDConnectService Stats\n"); 2491 2937 printf(" => number of worker threads: %d\n", mWorkers.Count()); 2938 LOG(("ipcDConnectService Stats\n")); 2939 LOG((" => number of worker threads: %d\n", mWorkers.Count())); 2492 2940 #endif 2493 2941 … … 2531 2979 const nsXPTType &type, 2532 2980 PRUint16 methodIndex, 2533 PRUint8 paramIndex,2534 2981 nsXPTCMiniVariant *dispatchParams, 2535 PRBool is FullVariantArray,2982 PRBool isXPTCVariantArray, 2536 2983 nsID &result) 2537 2984 { … … 2556 3003 return NS_ERROR_UNEXPECTED; 2557 3004 2558 nsID *p; 2559 if (isFullVariantArray) 2560 p = (nsID *) ((nsXPTCVariant *) dispatchParams)[argnum].val.p; 2561 else 2562 p = (nsID *) dispatchParams[argnum].val.p; 3005 nsID *p = (nsID *) GET_PARAM(dispatchParams, isXPTCVariantArray, argnum).val.p; 2563 3006 if (!p) 2564 3007 return NS_ERROR_UNEXPECTED; … … 3130 3573 ipcDConnectService::OnRelease(PRUint32 peer, const DConnectRelease *release) 3131 3574 { 3132 LOG(("ipcDConnectService::OnRelease [peer=%u instance=%p]\n", 3575 LOG(("ipcDConnectService::OnRelease [peer=%u instance=%p]\n", 3133 3576 peer, release->instance)); 3134 3577 … … 3216 3659 3217 3660 // XXX are inout params an issue? 3661 // yes, we will need to do v.ptr = &v.val for them (DeserializeParam doesn't 3662 // currently do that) to let the callee correctly pick it up and change. 3218 3663 3219 3664 if (paramInfo.IsIn() && !paramInfo.IsDipper()) … … 3227 3672 3228 3673 // fixup any interface pointers. we do this with a second pass so that 3229 // we can properly handle INTERFACE_IS. 3674 // we can properly handle INTERFACE_IS. This pass is also used to deserialize 3675 // arrays (array data goes after all other params). 3230 3676 for (i=0; i<paramCount; ++i) 3231 3677 { 3232 3678 const nsXPTParamInfo ¶mInfo = methodInfo->GetParam(i); 3233 const nsXPTType &type = paramInfo.GetType(); 3234 3235 if (paramInfo.IsIn() && type.IsInterfacePointer()) 3236 { 3237 PtrBits bits = (PtrBits) params[i].ptr; 3238 if (bits & 0x1) 3239 { 3240 // pointer is to a remote object. we need to build a stub. 3241 params[i].ptr = (void *) (bits & ~0x1); 3242 3679 if (paramInfo.IsIn()) 3680 { 3681 const nsXPTType &type = paramInfo.GetType(); 3682 if (type.IsInterfacePointer()) 3683 { 3684 // grab the DConAddr value temporarily stored in the param 3685 PtrBits bits = (PtrBits) params[i].val.p; 3686 3687 // DeserializeInterfaceParamBits needs IID only if it's a remote object 3243 3688 nsID iid; 3244 rv = GetIIDForMethodParam(iinfo, methodInfo, paramInfo, type, 3245 invoke->method_index, i, params, PR_TRUE, iid); 3246 if (NS_SUCCEEDED(rv)) 3689 if (bits & PTRBITS_REMOTE_BIT) 3247 3690 { 3248 DConnectStub *stub; 3249 rv = CreateStub(iid, peer, (DConAddr) params[i].ptr, &stub); 3250 if (NS_SUCCEEDED(rv)) 3251 { 3252 params[i].val.p = params[i].ptr = stub; 3253 params[i].SetValIsInterface(); 3254 } 3691 rv = GetIIDForMethodParam(iinfo, methodInfo, paramInfo, type, 3692 invoke->method_index, params, PR_TRUE, iid); 3693 if (NS_FAILED(rv)) 3694 goto end; 3255 3695 } 3696 3697 nsISupports *obj = nsnull; 3698 rv = DeserializeInterfaceParamBits(bits, peer, iid, obj); 3256 3699 if (NS_FAILED(rv)) 3257 3700 goto end; 3258 } 3259 else if (bits) 3260 { 3261 // pointer is to one of our instance wrappers. 3262 3263 DConnectInstance *wrapper = (DConnectInstance *) params[i].ptr; 3264 // make sure we've been sent a valid wrapper 3265 if (!CheckInstanceAndAddRef(wrapper)) 3266 { 3267 NS_NOTREACHED("instance wrapper not found"); 3268 rv = NS_ERROR_INVALID_ARG; 3701 3702 params[i].val.p = obj; 3703 // mark as interface to let FinishParam() release this param 3704 params[i].SetValIsInterface(); 3705 } 3706 else if (type.IsArray()) 3707 { 3708 void *array = nsnull; 3709 rv = DeserializeArrayParam(this, reader, peer, iinfo, 3710 invoke->method_index, *methodInfo, params, 3711 PR_TRUE, paramInfo, PR_FALSE, array); 3712 if (NS_FAILED(rv)) 3269 3713 goto end; 3270 } 3271 params[i].val.p = params[i].ptr = wrapper->RealInstance(); 3272 wrapper->Release(); 3273 // do not mark as an interface -- doesn't need to be freed 3274 } 3275 else 3276 { 3277 params[i].val.p = params[i].ptr = nsnull; 3278 // do not mark as an interface -- doesn't need to be freed 3714 3715 params[i].val.p = array; 3716 // mark to let FinishParam() free this param 3717 params[i].SetValIsAllocated(); 3279 3718 } 3280 3719 } … … 3313 3752 end: 3314 3753 LOG(("sending INVOKE_REPLY: rv=%x\n", rv)); 3315 3754 3316 3755 // balance CheckInstanceAndAddRef() 3317 3756 if (wrapper) … … 3350 3789 nsID iid; 3351 3790 rv = GetIIDForMethodParam(iinfo, methodInfo, paramInfo, type, 3352 invoke->method_index, i,params, PR_TRUE, iid);3791 invoke->method_index, params, PR_TRUE, iid); 3353 3792 if (NS_SUCCEEDED(rv)) 3354 3793 rv = SerializeInterfaceParam(writer, peer, iid, 3355 3794 (nsISupports *) params[i].val.p, wrappers); 3356 3357 // mark as an interface to let FinishParam() to release this param3358 if (NS_SUCCEEDED(rv))3359 params[i].SetValIsInterface();3360 3795 } 3361 3796 else … … 3369 3804 } 3370 3805 } 3806 3807 if (NS_SUCCEEDED(rv)) 3808 { 3809 // serialize output array parameters after everything else since the 3810 // deserialization procedure will need to get a size_is value which may be 3811 // stored in any preceeding or following param 3812 for (i=0; i<paramCount; ++i) 3813 { 3814 const nsXPTParamInfo ¶mInfo = methodInfo->GetParam(i); 3815 3816 if (paramInfo.GetType().IsArray() && 3817 (paramInfo.IsRetval() || paramInfo.IsOut())) 3818 { 3819 rv = SerializeArrayParam(this, writer, peer, iinfo, invoke->method_index, 3820 *methodInfo, params, PR_TRUE, paramInfo, 3821 params[i].val.p, wrappers); 3822 if (NS_FAILED(rv)) 3823 { 3824 reply.result = rv; 3825 break; 3826 } 3827 } 3828 } 3829 } 3371 3830 } 3372 3831 … … 3383 3842 if (params) 3384 3843 { 3844 // free individual elements of arrays (note: before freeing arrays 3845 // themselves in FinishParam()) 3846 for (i=0; i<paramUsed; ++i) 3847 { 3848 const nsXPTParamInfo ¶mInfo = methodInfo->GetParam(i); 3849 if (paramInfo.GetType().IsArray()) 3850 FinishArrayParam(iinfo, invoke->method_index, *methodInfo, 3851 params, PR_TRUE, paramInfo, params[i]); 3852 } 3853 3385 3854 for (i=0; i<paramUsed; ++i) 3386 3855 FinishParam(params[i]); -
trunk/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.h
r4863 r6850 185 185 }; 186 186 187 // used elsewhere like nsAtomTable to safely represent the integral value 188 // of an address. 189 typedef unsigned long PtrBits; 190 191 // bit flag that defines if a PtrBits value represents a remote object 192 #define PTRBITS_REMOTE_BIT 0x1 193 187 194 class DConnectStub; 188 195 typedef nsDataHashtable<DConnectStubKey, DConnectStub *> DConnectStubMap; … … 209 216 const nsXPTType &type, 210 217 PRUint16 methodIndex, 211 PRUint8 paramIndex,212 218 nsXPTCMiniVariant *dispatchParams, 213 PRBool is FullVariantArray,219 PRBool isXPTCVariantArray, 214 220 nsID &result); 215 221 … … 218 224 nsISupports *obj, 219 225 nsVoidArray &wrappers); 226 NS_HIDDEN_(nsresult) DeserializeInterfaceParamBits(PtrBits bits, PRUint32 peer, 227 const nsID &iid, 228 nsISupports *&obj); 220 229 221 230 NS_HIDDEN_(nsresult) SerializeException(ipcMessageWriter &writer, … … 241 250 PRLock *StubLock() { return mStubLock; } 242 251 PRLock *StubQILock() { return mStubQILock; } 243 252 244 253 static nsRefPtr <ipcDConnectService> GetInstance() { 245 254 return nsRefPtr <ipcDConnectService> (mInstance); … … 293 302 // our IPC client ID 294 303 PRUint32 mSelfID; 295 304 296 305 // global lock to protect access to protect DConnectStub::QueryInterface() 297 306 // (we cannot use mStubLock because it isn't supposed to be held long,
Note:
See TracChangeset
for help on using the changeset viewer.