How to check caller is EP in X++ - client

I need to check in X++ if the caller is EP or Client so I can do some customization if the caller is EP in that code. Please let me know how is it possible
Note: I am using ListPageInteraction class for both EP and AX Client and I have to made some modification to same query (used for both) in case the caller is EP in ListPageInteraction class

Check the NumberSeqNumCache.isEpClient method, it looks like this:
/// <summary>
/// Determines whether the request is from EP.
/// </summary>
/// <returns>
/// true if EP is the caller; otherwise, false.
/// </returns>
static server boolean isEpClient()
{
xSession session = new xsession();
boolean isEP = false;
sysClientSessions clientsessions;
;
select ClientType from clientsessions where clientsessions.SessionId == session.sessionId();
if (clientSessions.ClientType == SessionType::WebUser || clientsessions.clientType == SessionType::Worker)
{
isEp = true;
}
return isEp;
}
It checks if the current session is of type webuser or worker. If you ware using a client, the session would be of type SessionType::GUI. Mind though that other sessions may also register as type SessionType::Worker, for example batch tasks so this might not work everywhere.

Related

ruby c extension how to manage garbage collection between 2 objects

I have a C extension in which I have a main class (class A for example) created with the classical:
Data_Wrap_Struct
rb_define_alloc_func
rb_define_private_method(mymodule, "initialize" ...)
This A class have an instance method that generate B object. Those B objects can only be generated from A objects and have C data wrapped that depends on the data wrapped in the A instance.
I the A object are collected by the garbage collector before a B object, this could result in a Seg Fault.
How can I tell the GC to not collect a A instance while some of his B objects are still remaining. I guess I have to use rb_gc_mark or something like that. Should I have to mark the A instance each time a B object is created ??
Edit : More specifics Informations
I am trying to write a Clang extension. With clang, you first create a CXIndex, from which you can get a CXTranslationUnit, from which you can get a CXDiagnostic and or a CXCursor and so on. here is a simple illustration:
Clangc::Index#new => Clangc::Index
Clangc::Index#create_translation_unit => Clangc::TranslationUnit
Clangc::TranslationUnit#diagnostic(index) => Clangc::Diagnostic
You can see some code here : https://github.com/cedlemo/ruby-clangc
Edit 2 : A solution
The stuff to build the "b" objects with a reference to the "a" object:
typedef struct B_t {
void * data;
VALUE instance_of_a;
} B_t;
static void
c_b_struct_free(B_t *s)
{
if(s)
{
if(s->data)
a_function_to_free_the_data(s->data);
ruby_xfree(s);
}
}
static void
c_b_mark(void *s)
{
B_t *b =(B_t *)s;
rb_gc_mark(b->an_instance_of_a);
}
VALUE
c_b_struct_alloc( VALUE klass)
{
B_t * ptr;
ptr = (B_t *) ruby_xmalloc(sizeof(B_t));
ptr->data = NULL;
ptr->an_instance_of_a = Qnil;
return Data_Wrap_Struct(klass, c_b_mark, c_b_struct_free, (void *) ptr);
}
The c function that is used to build a "b" object from an "a" object:
VALUE c_A_get_b_object( VALUE self, VALUE arg)
{
VALUE mModule = rb_const_get(rb_cObject, rb_intern("MainModule"));\
VALUE cKlass = rb_const_get(mModule, rb_intern("B"));
VALUE b_instance = rb_class_new_instance(0, NULL, cKlass);
B_t *b;
Data_Get_Struct(b_instance, B_t, b);
/*
transform ruby value arg to C value c_arg
*/
b->data = function_to_fill_the_data(c_arg);
b->instance_of_a = self;
return b_instance;
}
In the Init_mainModule function:
void Init_mainModule(void)
{
VALUE mModule = rb_define_module("MainModule");
/*some code ....*/
VALUE cKlass = rb_define_class_under(mModule, "B", rb_cObject);
rb_define_alloc_func(cKlass, c_b_struct_alloc);
}
Same usage of the rb_gc_mark can be found in mysql2/ext/mysql2/client.c ( rb_mysql_client_mark function) in the project https://github.com/brianmario/mysql2
In the mark function for your B class, you should mark the A Ruby object, telling the garbage collector not to garbage collect it.
The mark function can be specified as the second argument to Data_Wrap_Struct. You might need to modify your design somehow to expose a pointer to the A objects.
Another option is to let the A object be an instance variable of the B object. You should probably do this anyway so that Ruby code can obtain the A object from the B object. Doing this would have the side effect of making the garbage collector not collect the A before the B, but you should not be relying on this side effect because it would be possible for your Ruby code to accidentally mess up the instance variable and then cause a segmentation fault.
Edit: Another option is to use reference counting of the shared C data. Then when the last Ruby object that is using that shared data gets garbage collected, you would delete the shared data. This would involve finding a good, cross-platform, thread-safe way to do reference counting so it might not be trivial.

Creating N number of instances of MFC application

Can someone please tell me how to go about creating a maximum of N instances of an application in MFC?
Also, if N instances are running, and one instance gets closed, then one new instance can be created (but no more than N instances can run at any one time).
Thank you in advance.
a.
You can create a global semaphore that up to n process instances can enter. The n+1 th instance of your process will fail to enter the semaphore. Of course you should select a short timeout for the locking operation so you can present a meaningful feedback to the user.
For the semaphore stuff you can take a look at MSDN.
I'd use lock files. In your CMyApp::InitInstance() add:
CString Path;
// better get the path to the global app data or local user app data folder,
// depending on if you want to allow the three instances machine-wide or per user.
// Windows' file system virtualization will make GetModuleFileName() per user:
DWORD dw = GetModuleFileName(m_hInstance,
Path.GetBuffer(MAX_PATH), MAX_PATH);
Path.ReleaseBuffer();
// strip "exe" from filename and replace it with "lock"
Path = Path.Left(Path.GetLength()-3) + T("lock");
int i;
// better have the locking file in your class and do a clean Close on ExitInstance()!
CFile *pLockingFile = NULL;
for (i = 0; i < 3; i++) // restrict to three instances
{
CString Counter;
Counter.Format(T("%d"), i);
TRY
{
pLockingFile = new CFile(Path + Counter,
CFile::modeCreate|CFile::modeWrite|CFile::shareExclusive);
pLockingFile.Close();
break; // got an instance slot
}
CATCH( CFileException, e )
{
// maybe do something else here, if file open fails
}
END_CATCH
if (i >= 3)
return TRUE; // close instance, no slot available
}
Edit: To lock the software machine-wide, retrieve the common app folder using the following function instead of calling GetModuleFileName().
#pragma warning(disable: 4996) // no risk, no fun
BOOL GetCommonAppDataPath(char *path)
{
*path = '\0';
if (SHGetSpecialFolderPath(NULL, path, CSIDL_COMMON_APPDATA, TRUE))
{
strcat(path, T("\\MyApplication")); // usually found under C:\ProgramData\MyApplication
DWORD dwFileStat = GetFileAttributes(path);
if (dwFileStat == 0xffffffff) // no MyApplication directory yet?
CreateDirectory(path, NULL); // create it
dwFileStat = GetFileAttributes(path); // 2nd try, just to be sure
if (dwFileStat == 0xffffffff || !(dwFileStat & FILE_ATTRIBUTE_DIRECTORY))
return FALSE;
return TRUE;
}
return FALSE;
}
Note: This will only work from Vista on. If you have XP, writing to a global directory is an easy task, e.g. C:\Windows\Temp. I have put the function in a helper dll I only load if the OS is Vista or higher. Otherwise your software won't start because of unresolved references in system dlls.

modify captured array c++11 lambda function

I'm writing an Windows phone application with C++/CX. The function tries to copy input array to output array asynchronously:
IAsyncAction CopyAsync(const Platform::Array<byte, 1>^ input, Platform::WriteOnlyArray<byte, 1>^ output)
{
byte *inputData = input->Data;
byte *outputData = output->Data;
int byteCount = input->Length;
// if I put it here, there is no error
//memcpy_s(outputData, byteCount, inputData, byteCount);
return concurrency::create_async([&]() -> void {
memcpy_s(outputData, byteCount, inputData, byteCount); // access violation exception
return;
});
}
This function compiles but cannot run correctly and produces an "Access violation exception". How can I modify values in the output array?
This is Undefined Behaviour: by the time you use your 3 captured (by reference) variables inputData/outputData/byteCount in the lambda, you already returned from CopyAsync and the stack has been trashed.
It's really the same issue as if you returned a reference to a local variable from a function (which we know is evil), except that here the references are hidden inside the lambda so it's a bit harder to see at first glance.
If you are sure that input and output won't change and will still be reachable between the moment you call CopyAsync and the moment you run the asynchronous action, you can capture your variables by value instead of by reference:
return concurrency::create_async([=]() -> void {
// ^ here
memcpy_s(outputData, byteCount, inputData, byteCount);
return;
});
Since they're only pointers (and an int), you won't be copying the pointed-to data, only the pointers themselves.
Or you could just capture input and output by value: since they're garbage-collected pointers this will at least make sure the objects are still reachable by the time you run the lambda:
return concurrency::create_async([=]() -> void {
memcpy_s(output->Data, input->Length, input->Data, input->Length);
return;
});
I for one prefer this second solution, it provides more guarantees (namely, object reachability) than the first one.

implementing a scheduler class in Windows

I want to implement a scheduler class, which any object can use to schedule timeouts and cancel then if necessary. When a timeout expires, this information will be sent to the timeout setter/owner at that time asynchronously.
So, for this purpose, I have 2 fundamental classes WindowsTimeout and WindowsScheduler.
class WindowsTimeout
{
bool mCancelled;
int mTimerID; // Windows handle to identify the actual timer set.
ITimeoutReceiver* mSetter;
int cancel()
{
mCancelled = true;
if ( timeKillEvent(mTimerID) == SUCCESS) // Line under question # 1
{
delete this; // Timeout instance is self-destroyed.
return 0; // ok. OS Timer resource given back.
}
return 1; // fail. OS Timer resource not given back.
}
WindowsTimeout(ITimeoutReceiver* setter, int timerID)
{
mSetter = setter;
mTimerID = timerID;
}
};
class WindowsScheduler
{
static void CALLBACK timerFunction(UINT uID,UINT uMsg,DWORD dwUser,DWORD dw1,DWORD dw2)
{
WindowsTimeout* timeout = (WindowsTimeout*) uMsg;
if (timeout->mCancelled)
delete timeout;
else
timeout->mDestination->GEN(evTimeout(timeout));
}
WindowsTimeout* schedule(ITimeoutReceiver* setter, TimeUnit t)
{
int timerID = timeSetEvent(...);
if (timerID == SUCCESS)
{
return WindowsTimeout(setter, timerID);
}
return 0;
}
};
My questions are:
Q.1. When a WindowsScheduler::timerFunction() call is made, this call is performed in which context ? It is simply a callback function and I think, it is performed by the OS context, right ? If it is so, does this calling pre-empt any other tasks already running ? I mean do callbacks have higher priority than any other user-task ?
Q.2. When a timeout setter wants to cancel its timeout, it calls WindowsTimeout::cancel().
However, there is always a possibility that timerFunction static call to be callbacked by OS, pre-empting the cancel operation, for example, just after mCancelled = true statement. In such a case, the timeout instance will be deleted by the callback function.
When the pre-empted cancel() function comes again, after the callback function completes execution, will try to access an attribute of the deleted instance (mTimerID), as you can see on the line : "Line under question # 1" in the code.
How can I avoid such a case ?
Please note that, this question is an improved version of the previos one of my own here:
Windows multimedia timer with callback argument
Q1 - I believe it gets called within a thread allocated by the timer API. I'm not sure, but I wouldn't be surprised if the thread ran at a very high priority. (In Windows, that doesn't necessarily mean it will completely preempt other threads, it just means it will get more cycles than other threads).
Q2 - I started to sketch out a solution for this, but then realized it was a bit harder than I thought. Personally, I would maintain a hash table that maps timerIDs to your WindowsTimeout object instances. The hash table could be a simple std::map instance that's guarded by a critical section. When the timer callback occurs, it enters the critical section and tries to obtain the WindowsTimer instance pointer, and then flags the WindowsTimer instance as having been executed, exits the critical section, and then actually executes the callback. In the event that the hash table doesn't contain the WindowsTimer instance, it means the caller has already removed it. Be very careful here.
One subtle bug in your own code above:
WindowsTimeout* schedule(ITimeoutReceiver* setter, TimeUnit t)
{
int timerID = timeSetEvent(...);
if (timerID == SUCCESS)
{
return WindowsTimeout(setter, timerID);
}
return 0;
}
};
In your schedule method, it's entirely possible that the callback scheduled by timeSetEvent will return BEFORE you can create an instance of WindowsTimeout.

Win32: How to get the process/thread that owns a mutex?

I'm working an application of which only one instance must exist at any given time. There are several possibilities to accomplish this:
Check running processes for one matching our EXE's name (unreliable)
Find the main window (unreliable, and I don't always have a main window)
Create a mutex with a unique name (GUID)
The mutex option seems to me the most reliable and elegant.
However, before my second instance terminates, I want to post a message to the already running instance. For this, I need a handle to the thread (or the process) that owns the mutex.
However, there seems to be no API function to get the creator/owner of a given mutex. Am I just overlooking it? Is there another way to get to this thread/process? Is there another way to go about this?
Update: This guy simply broadcast a message to all running processes. I guess that's possible, but I don't really like it...
This should get you started on the original request to get a process that owns a mutex.
It's in C#, but the Win32 calls are the same.
class HandleInfo
{
[DllImport("ntdll.dll", CharSet = CharSet.Auto)]
public static extern uint NtQuerySystemInformation(int SystemInformationClass, IntPtr SystemInformation, int SystemInformationLength, out int ReturnLength);
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern IntPtr VirtualAlloc(IntPtr address, uint numBytes, uint commitOrReserve, uint pageProtectionMode);
[DllImport("kernel32.dll", SetLastError=true)]
internal static extern bool VirtualFree(IntPtr address, uint numBytes, uint pageFreeMode);
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEM_HANDLE_INFORMATION
{
public int ProcessId;
public byte ObjectTypeNumber;
public byte Flags; // 1 = PROTECT_FROM_CLOSE, 2 = INHERIT
public short Handle;
public int Object;
public int GrantedAccess;
}
static uint MEM_COMMIT = 0x1000;
static uint PAGE_READWRITE = 0x04;
static uint MEM_DECOMMIT = 0x4000;
static int SystemHandleInformation = 16;
static uint STATUS_INFO_LENGTH_MISMATCH = 0xC0000004;
public HandleInfo()
{
IntPtr memptr = VirtualAlloc(IntPtr.Zero, 100, MEM_COMMIT, PAGE_READWRITE);
int returnLength = 0;
bool success = false;
uint result = NtQuerySystemInformation(SystemHandleInformation, memptr, 100, out returnLength);
if (result == STATUS_INFO_LENGTH_MISMATCH)
{
success = VirtualFree(memptr, 0, MEM_DECOMMIT);
memptr = VirtualAlloc(IntPtr.Zero, (uint)(returnLength + 256), MEM_COMMIT, PAGE_READWRITE);
result = NtQuerySystemInformation(SystemHandleInformation, memptr, returnLength, out returnLength);
}
int handleCount = Marshal.ReadInt32(memptr);
SYSTEM_HANDLE_INFORMATION[] returnHandles = new SYSTEM_HANDLE_INFORMATION[handleCount];
using (StreamWriter sw = new StreamWriter(#"C:\NtQueryDbg.txt"))
{
sw.WriteLine("# Offset\tProcess Id\tHandle Id\tHandleType");
for (int i = 0; i < handleCount; i++)
{
SYSTEM_HANDLE_INFORMATION thisHandle = (SYSTEM_HANDLE_INFORMATION)Marshal.PtrToStructure(
new IntPtr(memptr.ToInt32() + 4 + i * Marshal.SizeOf(typeof(SYSTEM_HANDLE_INFORMATION))),
typeof(SYSTEM_HANDLE_INFORMATION));
sw.WriteLine("{0}\t{1}\t{2}\t{3}", i.ToString(), thisHandle.ProcessId.ToString(), thisHandle.Handle.ToString(), thisHandle.ObjectTypeNumber.ToString());
}
}
success = VirtualFree(memptr, 0, MEM_DECOMMIT);
}
}
I don't think there is a trivial way to resolve the actual owner of a Mutex, but the process that owns it can create other secondary items whose lifetimes are tied to it. There are plenty of mechanisms that are suitable for calling back across-process without having a main window.
Register an object in the COM Running Object Table. Clients that are unable to take ownership of the Mutex can lookup the owner via the ROT and call back to the owner. A File Moniker should be suitable for registration here.
Create a chunk of shared memory containing location details for the owner process. From there, write into the buffer the process handle and thread handle of a thread that can receive windows messages, and then use PostThreadMessage() to send a notification. Any other competing process may open the shared memory for read-only to determine where to send a windows message.
Listen in the owner process on a Socket or Named Pipe. Probably overkill and not a good match for your needs.
Use a shared file with locking. I'm not fond of this because the owner will need to poll, and it won't gracefully handle N potential other processes that could be trying to contact the owner at the same time.
Here are reference links for the first two options.
IRunningObjectTable # MSDN ,
File Monikers # MSDN
Creating Named Shared Memory # MSDN
I have never really understood the rational behind using a Mutex which has no signaling capability. I would instead create an event (using CreateEvent) which has the same properties as creating a mutex (i.e. with a name it can return that the object already existed) but you can set the event flag in the new process, as long as the original process is waiting on the event flag it can be notified when it needs to wake itself up.
You could always do it the UNIX way and create a "pid" file, putting the process id of the currently running instance into that file. Then have the app delete the file when it exits.
When a new instance starts up it should verify that the process in the PID file is actually alive as well (in case the app exits abnormally and the file doesn't get deleted)
Create a shared memory area with the fixed name:
http://msdn.microsoft.com/en-us/library/aa366551%28VS.85%29.aspx
Then you can put any structure you like inside, including process id, HWND etc.
There's a portable option: create a socket on a port (with a fixed number) and wait (accept) on it. The second instance of the app will fail since the port is already taken. Then the second instance can connect to the socket of the primary instance and send any information desired.
I hope this helps...
I had similar problems. I am want a function that returns if a single instance of an app is running. Then another function to bring the app to the front. In which I must first deduce the HWND of the already running window.
FindWindow sucks big time. Window titles can change, another window could be using the same class and title, etc.
Then I thought maybe extra data could be stored with a mutex. But I dont see where user data can be stored in a mutex object or event object. But a mutex knows which thread it belongs to and thus which process it belongs to. But as you said, the api doesnt seem to exist.
Many new and complicated looking methods have been suggested here; with the exeception of simply using a file. So I want to add another method, temporary registry keys.
This method is easiest for me as I already built an hkey library. But the win32 registry api is pretty straight forward compared to the horrifying looking shared memory method.

Resources