[Mono-bugs] [Bug 70429][Maj] Changed - find_method failed in assembly loaded using mono_image_open_from_data from preload_hook
bugzilla-daemon@bugzilla.ximian.com
bugzilla-daemon@bugzilla.ximian.com
Tue, 28 Dec 2004 17:20:02 -0500 (EST)
Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.
Changed by ymeng@bloomberg.net.
http://bugzilla.ximian.com/show_bug.cgi?id=70429
--- shadow/70429 2004-12-10 11:41:18.000000000 -0500
+++ shadow/70429.tmp.9795 2004-12-28 17:20:02.000000000 -0500
@@ -1,14 +1,14 @@
Bug#: 70429
Product: Mono: Runtime
Version: 1.1
-OS:
+OS: unknown
OS Details: Window XP
Status: NEW
Resolution:
-Severity:
+Severity: Unknown
Priority: Major
Component: misc
AssignedTo: mono-bugs@ximian.com
ReportedBy: ymeng@bloomberg.net
QAContact: mono-bugs@ximian.com
TargetMilestone: ---
@@ -280,6 +280,114 @@
}
Please consider adding such a function or fix the existing
image_open_from_data such that it behaves the same as the file based open
+
+------- Additional Comments From ymeng@bloomberg.net 2004-12-28 17:20 -------
+*** Update ***
+
+The above code causes problem when we tried to load multiple versions
+of the same-named assembly. In that case the older assembly is always
+used. The following code fixes the problem:
+
+MonoImage *
+mono_image_open_from_data_with_name(const char *name, char *data,
+guint32 data_len, gboolean need_copy, MonoImageOpenStatus *status)
+{
+ MonoCLIImageInfo *iinfo;
+ MonoImage *image, *image2;
+ char *datac;
+ char *imgName;
+
+ g_return_val_if_fail (name != NULL, NULL);
+
+
+ /*
+ * The easiest solution would be to do all the loading inside
+the mutex,
+ * but that would lead to scalability problems. So we let the
+loading
+ * happen outside the mutex, and if multiple threads happen
+to load
+ * the same image, we discard all but the first copy.
+ */
+ imgName = g_strdup(name);
+
+ EnterCriticalSection (&images_mutex);
+ image = g_hash_table_lookup (loaded_images_hash, imgName);
+
+ if (image){
+ if ((image->raw_data_len == data_len) && ( 0==memcmp
+(image->raw_data, data, data_len))){
+ image->ref_count++;
+ LeaveCriticalSection (&images_mutex);
+ return image;
+ }
+ // newer image data is being loaded, close the old
+image
+ mono_image_close(image);
+
+ }
+
+ LeaveCriticalSection (&images_mutex);
+
+
+ if (!data || !data_len) {
+ if (status)
+ *status = MONO_IMAGE_IMAGE_INVALID;
+ return NULL;
+ }
+ datac = data;
+ if (need_copy) {
+ datac = g_try_malloc (data_len);
+ if (!datac) {
+ if (status)
+ *status = MONO_IMAGE_ERROR_ERRNO;
+ return NULL;
+ }
+ memcpy (datac, data, data_len);
+ }
+
+ image = g_new0 (MonoImage, 1);
+ image->ref_count = 1;
+ image->raw_data = datac;
+ image->raw_data_len = data_len;
+ image->raw_data_allocated = need_copy;
+ image->name = imgName;
+ iinfo = g_new0 (MonoCLIImageInfo, 1);
+ image->image_info = iinfo;
+
+
+ image = do_mono_image_load(image, status);
+
+
+ if (image == NULL)
+ return NULL;
+
+ EnterCriticalSection (&images_mutex);
+ image2 = g_hash_table_lookup (loaded_images_hash, image-
+>name);
+
+ if (image2) {
+ /* Somebody else beat us to it */
+ image2->ref_count ++;
+ LeaveCriticalSection (&images_mutex);
+ mono_image_close (image);
+ return image2;
+ }
+ g_hash_table_insert (loaded_images_hash, image->name, image);
+ if (image->assembly_name && (g_hash_table_lookup
+(loaded_images_hash, image->assembly_name) == NULL))
+ g_hash_table_insert (loaded_images_hash, (char *)
+image->assembly_name, image);
+ g_hash_table_insert (loaded_images_guid_hash, image->guid,
+image);
+ LeaveCriticalSection (&images_mutex);
+
+ return image;
+
+
+}
+
+