test/testlock.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 28 Nov 2014 04:51:33 -0800
changeset 9246 a761913e5e91
parent 8149 681eb46b8ac4
child 9356 e87d6e1e812a
permissions -rw-r--r--
Fixed bug 2786 - "UCS-2-INTERNAL" iconv encoding is not supported everywhere, use UTF-16LE instead

Jonas Kulla

src/main/windows/SDL_windows_main.c:137:
cmdline = SDL_iconv_string("UTF-8", "UCS-2-INTERNAL", (char *)(text), (SDL_wcslen(text)+1)*sizeof(WCHAR));

I'm trying to compile an SDL2 application for windows using the mingw-w64 32bit toolchain provided by my distro (Fedora 19). However, even the simplest test program that does nothing at all fails to startup with a "Fatal error - out of memory" message because the mingw iconv library provided by my distro does not support the "UCS-2-INTERNAL" encoding and the conversion returns null.

From my little bit of research, it turns out that even though this encoding is supported by the external GNU libiconv library, some glibc versions (?) don't support it with their internal iconv routines, and will instead provide the native endian encoding when "UCS-2" is specified.

Nonetheless, I wonder why the native endianness is considered in the first place when Windows doesn't even run on any big endian archs (to my knowledge). And true enough, 'WIN_StringToUTF8' from core/windows/SDL_windows.h is used everywhere else in the windows backend, which is just a macro to iconv with "UTF-16LE" as source. Therefore it would IMO make sense to use this macro here as well, which would solve my problem (patch attached).
slouken@5535
     1
/*
slouken@8149
     2
  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
slouken@5535
     3
slouken@5535
     4
  This software is provided 'as-is', without any express or implied
slouken@5535
     5
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     6
  arising from the use of this software.
slouken@5535
     7
slouken@5535
     8
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
     9
  including commercial applications, and to alter it and redistribute it
slouken@5535
    10
  freely.
slouken@5535
    11
*/
slouken@0
    12
slouken@7191
    13
/* Test the thread and mutex locking functions
slouken@0
    14
   Also exercises the system's signal/thread interaction
slouken@0
    15
*/
slouken@0
    16
slouken@0
    17
#include <signal.h>
slouken@0
    18
#include <stdio.h>
philipp@7442
    19
#include <stdlib.h> /* for atexit() */
slouken@0
    20
slouken@0
    21
#include "SDL.h"
slouken@0
    22
#include "SDL_mutex.h"
slouken@0
    23
#include "SDL_thread.h"
slouken@0
    24
slouken@0
    25
static SDL_mutex *mutex = NULL;
slouken@3578
    26
static SDL_threadID mainthread;
slouken@0
    27
static SDL_Thread *threads[6];
slouken@1769
    28
static volatile int doterminate = 0;
slouken@0
    29
icculus@1151
    30
/*
icculus@1151
    31
 * SDL_Quit() shouldn't be used with atexit() directly because
icculus@1151
    32
 *  calling conventions may differ...
icculus@1151
    33
 */
slouken@1895
    34
static void
slouken@1895
    35
SDL_Quit_Wrapper(void)
icculus@1151
    36
{
slouken@1895
    37
    SDL_Quit();
icculus@1151
    38
}
icculus@1151
    39
slouken@1895
    40
void
slouken@1895
    41
printid(void)
slouken@0
    42
{
aschiffler@7639
    43
    SDL_Log("Process %lu:  exiting\n", SDL_ThreadID());
slouken@0
    44
}
slouken@0
    45
slouken@1895
    46
void
slouken@1895
    47
terminate(int sig)
slouken@0
    48
{
slouken@1895
    49
    signal(SIGINT, terminate);
slouken@1895
    50
    doterminate = 1;
slouken@1895
    51
}
slouken@0
    52
slouken@1895
    53
void
slouken@1895
    54
closemutex(int sig)
slouken@1895
    55
{
slouken@3578
    56
    SDL_threadID id = SDL_ThreadID();
slouken@1895
    57
    int i;
aschiffler@7639
    58
    SDL_Log("Process %lu:  Cleaning up...\n", id == mainthread ? 0 : id);
slouken@2779
    59
    doterminate = 1;
slouken@1895
    60
    for (i = 0; i < 6; ++i)
slouken@2779
    61
        SDL_WaitThread(threads[i], NULL);
slouken@1895
    62
    SDL_DestroyMutex(mutex);
slouken@1895
    63
    exit(sig);
slouken@1895
    64
}
slouken@0
    65
slouken@1895
    66
int SDLCALL
slouken@1895
    67
Run(void *data)
slouken@1895
    68
{
slouken@1895
    69
    if (SDL_ThreadID() == mainthread)
slouken@1895
    70
        signal(SIGTERM, closemutex);
slouken@2779
    71
    while (!doterminate) {
aschiffler@7639
    72
        SDL_Log("Process %lu ready to work\n", SDL_ThreadID());
slouken@6977
    73
        if (SDL_LockMutex(mutex) < 0) {
aschiffler@7639
    74
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't lock mutex: %s", SDL_GetError());
slouken@1895
    75
            exit(1);
slouken@1895
    76
        }
aschiffler@7639
    77
        SDL_Log("Process %lu, working!\n", SDL_ThreadID());
slouken@1895
    78
        SDL_Delay(1 * 1000);
aschiffler@7639
    79
        SDL_Log("Process %lu, done!\n", SDL_ThreadID());
slouken@6977
    80
        if (SDL_UnlockMutex(mutex) < 0) {
aschiffler@7639
    81
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't unlock mutex: %s", SDL_GetError());
slouken@1895
    82
            exit(1);
slouken@1895
    83
        }
slouken@1895
    84
        /* If this sleep isn't done, then threads may starve */
slouken@1895
    85
        SDL_Delay(10);
slouken@2779
    86
    }
slouken@2779
    87
    if (SDL_ThreadID() == mainthread && doterminate) {
aschiffler@7639
    88
        SDL_Log("Process %lu:  raising SIGTERM\n", SDL_ThreadID());
slouken@2779
    89
        raise(SIGTERM);
slouken@1895
    90
    }
slouken@1895
    91
    return (0);
slouken@1895
    92
}
slouken@0
    93
slouken@1895
    94
int
slouken@1895
    95
main(int argc, char *argv[])
slouken@1895
    96
{
slouken@1895
    97
    int i;
slouken@1895
    98
    int maxproc = 6;
slouken@0
    99
aschiffler@7639
   100
	/* Enable standard application logging */
aschiffler@7639
   101
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
aschiffler@7639
   102
slouken@1895
   103
    /* Load the SDL library */
slouken@1895
   104
    if (SDL_Init(0) < 0) {
aschiffler@7639
   105
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s\n", SDL_GetError());
slouken@1895
   106
        exit(1);
slouken@1895
   107
    }
slouken@1895
   108
    atexit(SDL_Quit_Wrapper);
slouken@1895
   109
slouken@1895
   110
    if ((mutex = SDL_CreateMutex()) == NULL) {
aschiffler@7639
   111
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create mutex: %s\n", SDL_GetError());
slouken@1895
   112
        exit(1);
slouken@1895
   113
    }
slouken@1895
   114
slouken@1895
   115
    mainthread = SDL_ThreadID();
aschiffler@7639
   116
    SDL_Log("Main thread: %lu\n", mainthread);
slouken@1895
   117
    atexit(printid);
slouken@1895
   118
    for (i = 0; i < maxproc; ++i) {
icculus@5969
   119
        char name[64];
icculus@5969
   120
        SDL_snprintf(name, sizeof (name), "Worker%d", i);
icculus@5969
   121
        if ((threads[i] = SDL_CreateThread(Run, name, NULL)) == NULL)
aschiffler@7639
   122
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create thread!\n");
slouken@1895
   123
    }
slouken@1895
   124
    signal(SIGINT, terminate);
slouken@1895
   125
    Run(NULL);
slouken@1895
   126
slouken@1895
   127
    return (0);                 /* Never reached */
slouken@0
   128
}