@@ -63,14 +63,24 @@ accessible from a C function. See mqicb_c.go for the proxy/gateway C function th
63
63
//export MQCALLBACK_Go
64
64
func MQCALLBACK_Go (hConn C.MQHCONN , mqmd * C.MQMD , mqgmo * C.MQGMO , mqBuffer C.PMQVOID , mqcbc * C.MQCBC ) {
65
65
66
+ var cbHObj * MQObject
67
+
66
68
// Find the real callback function and invoke it
67
69
// Invoked function should match signature of the MQCB_FUNCTION type
68
70
gogmo := NewMQGMO ()
69
71
gomd := NewMQMD ()
70
72
gocbc := NewMQCBC ()
71
73
72
- copyGMOfromC (mqgmo , gogmo )
73
- copyMDfromC (mqmd , gomd )
74
+ // For EVENT callbacks, the GMO and MD may be NULL
75
+ if mqgmo != (C .PMQGMO )(C .NULL ) {
76
+ copyGMOfromC (mqgmo , gogmo )
77
+ }
78
+
79
+ if mqmd != (C .PMQMD )(C .NULL ) {
80
+ copyMDfromC (mqmd , gomd )
81
+ }
82
+
83
+ // This should never be NULL
74
84
copyCBCfromC (mqcbc , gocbc )
75
85
76
86
mqreturn := & MQReturn {MQCC : int32 (mqcbc .CompCode ),
@@ -79,16 +89,44 @@ func MQCALLBACK_Go(hConn C.MQHCONN, mqmd *C.MQMD, mqgmo *C.MQGMO, mqBuffer C.PMQ
79
89
}
80
90
81
91
key := makeKey (hConn , mqcbc .Hobj )
82
- if info , ok := cbMap [key ]; ok {
92
+ info , ok := cbMap [key ]
93
+
94
+ // The MQ Client libraries seem to sometimes call us with an EVENT
95
+ // even if it's not been registered. And therefore the cbMap does not
96
+ // contain a matching callback function with the hObj. It has
97
+ // been seen with a 2033 return (see issue #75).
98
+ //
99
+ // This feels like wrong behaviour from the client, but we need to find a
100
+ // way to deal with it even if it gets fixed in future.
101
+ // The way I've chosen is to find the first entry in
102
+ // the map associated with the hConn and call its registered function with
103
+ // a dummy hObj.
104
+ if ! ok {
105
+ if gocbc .CallType == MQCBCT_EVENT_CALL && mqcbc .Hobj == 0 {
106
+ key = makePartialKey (hConn )
107
+ for k , i := range cbMap {
108
+ if strings .HasPrefix (k , key ) {
109
+ ok = true
110
+ info = i
111
+ cbHObj = & MQObject {qMgr : info .hObj .qMgr , Name : "" }
112
+ // Only care about finding one match in the table
113
+ break
114
+ }
115
+ }
116
+ }
117
+ } else {
118
+ cbHObj = info .hObj
119
+ }
120
+
121
+ if ok {
83
122
84
123
gocbc .CallbackArea = info .callbackArea
85
124
gocbc .ConnectionArea = info .connectionArea
86
125
87
126
// Get the data
88
127
b := C .GoBytes (unsafe .Pointer (mqBuffer ), C .int (mqcbc .DataLength ))
89
-
90
128
// And finally call the user function
91
- info .callbackFunction (info . hObj , gomd , gogmo , b , gocbc , mqreturn )
129
+ info .callbackFunction (cbHObj , gomd , gogmo , b , gocbc , mqreturn )
92
130
}
93
131
}
94
132
0 commit comments