2010-02-16 16 views
7

OK, tôi nghi ngờ tôi sẽ gặp khó khăn ngay cả khi đặt điều này trong các từ vì sự hiểu biết của tôi về COM và căn hộ không thực sự đạt đến công việc ;-)Làm thế nào để đảm bảo không có quyền truy cập lại vào máy chủ COM chính-STA của tôi (C++)?

Tôi có một máy chủ COM/thành phần (C++) bao bọc một số mã cũ. Do các giới hạn của mã kế thừa này, tôi cần đảm bảo rằng các phương pháp của thành phần COM là:

  1. chỉ được gọi trên một chuỗi duy nhất.
  2. đây luôn là chủ đề giống nhau cho tất cả các phiên bản của máy chủ.
  3. (mà tôi chỉ nhận ra sau) không có cuộc gọi lại.

Hai số đầu tiên tôi đạt được bằng cách đăng ký máy chủ với ThreadingModel = "".

Thứ ba là một vấn đề mà tôi đã bất ngờ thậm chí gặp phải.

Máy chủ đang được một khách hàng đa luồng sử dụng mà tôi không có quyền kiểm soát. Nó tạo ra nhiều cá thể của máy chủ/thành phần trên các luồng khác nhau và gọi phương thức DoSomething() của chúng.

Điều này dẫn đến việc chọn hành vi treo và treo và tôi đã thấy các dấu vết ngăn xếp chứa hai lệnh gọi tới DoSomething() trên cả chuỗi STA chính, nhưng đối với các phiên bản khác nhau của máy chủ.

Ban đầu tôi thậm chí không nghĩ rằng điều này là có thể, nhưng bây giờ tôi có một sự hiểu biết một phần và tôi cần phải biết nếu/làm thế nào nó có thể được ngăn chặn.

Đọc của tôi cho thấy rằng tôi có thể cần phải sử dụng IMessageFilter theo một số thời trang, nhưng tôi không chắc liệu đây có phải là thứ có thể thực hiện ở phía máy chủ hay không hoặc do khách hàng thực hiện.

Ai đó có thể trợ giúp?

Hãy lưu ý rằng tôi đang tìm kiếm xem có câu trả lời nào ở cấp COM hay không, thay vì tìm kiếm các đề xuất về cách thay đổi cách mã máy chủ tương tác với mã cũ (ví dụ: riêng của chủ đề và thực hiện của riêng tôi (non-COM) marshalling của các cuộc gọi từ tất cả các trường hợp của máy chủ vào chủ đề đó).

Trả lời

5

COM nguyên soái gọi đến máy chủ của bạn thông qua vòng lặp tin nhắn. Bạn có thể nhận được vào địa ngục lại entrancy với vòng lặp mod modal. Vòng lặp đó sẽ xử lý các cuộc gọi đi cần phải được sắp xếp lại theo chuỗi khách hàng. Giống như các sự kiện. Hoặc gọi máy chủ của bạn đến máy chủ khác nằm trong một căn hộ STA khác. Trong khi vòng lặp phương thức bơm thông điệp, chờ cuộc gọi đi hoàn thành, nó có thể nhận cuộc gọi đến, giống như vòng lặp thông báo thông thường.

Về mặt kỹ thuật, việc ủy ​​thác lại cũng có thể xảy ra khi máy chủ của bạn đang cố gắng duy trì giao diện người dùng bằng cách tự bơm thông điệp.

Có, điều này có thể là rất khó giải quyết. Tôi không biết về bất kỳ sự sửa chữa ma thuật nào cho điều này, và tôi đã rất chăm chỉ trong một thời gian. Tôi cũng đã xem IMessageFilter và kết luận là vô dụng để giải quyết vấn đề này.

3

Ngăn chặn tái uỷ thác hoàn toàn theo kiểu chung chung có thể chứng minh hầu như không thể thực hiện do cách thực hiện marshalling COM, như nobugz đã mô tả rồi.Tôi đoán có thể phát hiện bằng tay hoặc bằng cách sử dụng "proxy" tùy chỉnh (ví dụ: The Guts of the Universal Delegator bởi Keith Brown).

Chỉ là một ý tưởng: Nếu đối tượng COM của bạn luôn chạy trong STA và chỉ được gọi từ khách hàng đang chạy trong các căn hộ khác (ví dụ: MTA), có thể bạn đọc trên custom marshalling (cảnh báo: không cho người yếu tim). Vì mã kế thừa của bạn dường như không có bất kỳ yêu cầu nào để chạy trong STA chính, hoặc tương tác cụ thể hơn với các thành phần GUI, điều này có thể chứng minh một sự thay thế.

2

Như nobugz chỉ ra, đây là một vấn đề do vòng lặp tin nhắn.

Tôi có thể xem giải quyết điều này bên trong đối tượng COM. Nó phụ thuộc vào sự phức tạp của các cuộc gọi của bạn nhưng bạn có thể xem xét việc có một hàng đợi công việc bên trong đối tượng COM của bạn được xử lý bởi một luồng đơn nằm dưới sự kiểm soát của bạn. Sau đó, bạn sắp xếp thủ công các tham số đầu vào của mình thành một khối dữ liệu mà bạn đăng lên hàng đợi, cuộc gọi COM của bạn sẽ chặn một sự kiện trong cấu trúc dữ liệu xếp hàng tùy chỉnh 'mỗi cuộc gọi' của bạn. Khi cuộc gọi được xử lý trên một luồng đang xử lý hàng đợi công việc của bạn, bạn trích xuất các tham số, thực hiện cuộc gọi và sau đó đóng gói kết quả vào cấu trúc dữ liệu tùy chỉnh và đặt sự kiện ... Cuộc gọi của bạn hiện có thể giải nén mọi thứ và quay lại.

Tất nhiên ma quỷ là chi tiết. Cá nhân tôi sử dụng IOCP để xây dựng hàng đợi tùy chỉnh nhưng đó chỉ là một chi tiết triển khai.

Có bạn đang làm nhiều công việc hơn nhưng đưa ra yêu cầu của bạn (một chủ đề để thực hiện tất cả các cuộc gọi và không có reentrancy) nó có lẽ là cách đáng tin cậy nhất để làm điều đó. Bạn có thể sau đó, tất nhiên, thả các yêu cầu STA cho các đối tượng COM thực tế chính nó như bạn đã thực hiện một đối tượng nhận biết luồng có thể chạy trong bất kỳ appartment ...

Các vấn đề liên quan